2014-01-24 3 views
0

У нас есть проект, основанный на HotTowel SPA от John Papa с использованием Angular, Breeze и UI-Bootstrap.Проблемы с клиентским кешированием запросов в проекте Angular + Breeze

Мы сталкиваемся с проблемами, использующими кеширование клиентов, для загрузки Drop-down из таблиц SQL Lookup. Представление загружается до кэширования данных, что приводит к пустым выпадающим спискам при первом загрузке представления. Если мы обновляем представление, затем падает капли вниз. Мы понимаем, что это проблема секвенирования и маршрутизации, но не может понять, как заставить ее работать.

Проблема, похоже, сосредоточена вокруг использования обещаний и способов распознавания, когда они успешно возвращаются. Мы используем основную функцию для загрузки кэшированных данных из базы данных при запуске, но представление поиска загружается до того, как данные доступны в функции getActionDomain().

Мы будем благодарны за любые указатели или идеи.

Спасибо,

JG

app.run в app.js является отправной точкой

(function() { 
    'use strict'; 

    var serviceId = 'app'; 
    var app = angular.module('app', [ 
     // Angular modules 
     'ngAnimate',  // animations 
     'ngRoute',   // routing 
     'ngSanitize',  // sanitizes html bindings (ex: sidebar.js) 
     // Custom modules 
     'common',   // common functions, logger, spinner 
     //'common.bootstrap', // bootstrap dialog wrapper functions 

     // 3rd Party Modules 
     'ui.bootstrap'  // ui-bootstrap (ex: carousel, pagination, dialog) 
    ]); 

    // Handle routing errors and success events 
    app.run(['$route', '$rootScope', '$location', '$http', 'Auth', 'datacontext', 'common', function ($route, $rootScope, $location, $http, Auth, datacontext, common) { 

     var getLogFn = common.logger.getLogFn; 
     var log = getLogFn(serviceId); 
     var logError = getLogFn(serviceId, 'error'); 
     var logSuccess = getLogFn(serviceId, 'success'); 
     var $q = common.$q; 

     //breeze.core.extendQ($rootScope, $q); 
     primeData(); 

     function primeData() { 

      return datacontext.prime() 
       .then(startRouting) 
       .then(querySucceeded, _queryFailed, null); 


      function querySucceeded(data) { 
       log('Retrieved [Lookups] from remote data source', data, true); 
       return true; 
      } 



     } 

     function startRouting() { 
      $rootScope.$on('$routeChangeStart', function (event, next, current) { 
       $rootScope.error = null; 

       if ($rootScope.user) { 
        return true; 
       } else { 
        $rootScope.user = {}; 

        var defered = $q.defer(); 

        checkRouting($q, $rootScope, $location); 

        return defered.promise; 
       } 

      }); 

      var checkRouting = function ($q, $rootScope, $location) { 
       var defered = $q.defer(); 

       Auth.getCurrentUser() 
        .then(function (data) { 
         $rootScope.user.isInUserGroup = data.data.IsInUserGroup; 
         $rootScope.user.firstName = data.data.FirstName.replace(/\"/g, ""); 
         $rootScope.user.lastName = data.data.LastName.replace(/\"/g, ""); 
         $rootScope.user.userName = data.data.UserName.replace(/\"/g, ""); 
        }); 

       return defered.promise; 
      }; 
     } 

     function _queryFailed(error) { 
      var msg = config.appErrorPrefix + 'Error priming data.' + error.message; 
      logError(msg, error); 
      throw error; 
     } 
    }]); 

})(); 

Основная функция находится в модуле datacontext.js:

function prime() { 
    if (primePromise) return primePromise; 

    var deferred = $q.defer(); 

    primePromise = $q.all([getLookupLists()]) 
     .then(extendMetadata) 
     .then(success); 

    function success() { 
     setLookups(); 
     dataPrimed = true; 
     //apps.startRouting(); 
     log('Primed the data'); 
    }; 

    function extendMetadata() { 
     var metadataStore = manager.metadataStore; 
     var types = metadataStore.getEntityTypes(); 
     types.forEach(function (type) { 
      if (type instanceof breeze.EntityType) { 
       set(type.shortName, type); 
      } 
     }); 

     function set(resourceName, entityName) { 
      metadataStore.setEntityTypeForResourceName(resourceName, entityName); 
     } 
    } 

    deferred.promise = primePromise; 
    return deferred.promise; 


} 

function setLookups() { 
    service.lookupCachedData = { 
     actions: _getAllLocal('ActionDomain', 'sortorder'), 
     statusCodes: _getAllLocal('StatusDomain', 'sortorder') 
    } 
} 

function _getAllLocal(resource, ordering) { 
    return EntityQuery.from(resource) 
    .orderBy(ordering) 
    .using(manager) 
    .executeLocally(); 
} 

function getLookupLists() { 
    return EntityQuery.from('Lookups') 
    .using(manager).execute() 
    .then(querySucceeded, _queryFailed); 

    function querySucceeded(data) { 
     log('Retrieved [Lookups] from remote data source', data, false); 
     return true; 
    } 

} 

Код вызывается в модуле контроллера view.js

function activate() { 
    common.activateController([getActionDomain(), getStatusDomain(), getCpuLog()], controllerId) 
     .then(function() { log('Activated search View', null, false); }); 
} 


function getActionDomain() { 
    if (datacontext.lookupCachedData && datacontext.lookupCachedData.actions) { 
     vm.actions.push({ value: 0 }); 
     datacontext.lookupCachedData.actions.forEach(function (actionItem) { 
      vm.actions.push(actionItem); 
     }) 
    } 
} 

function getStatusDomain() { 
    if (datacontext.lookupCachedData && datacontext.lookupCachedData.statusCodes) { 
     vm.statusList.push({ value: 0 }); 
     datacontext.lookupCachedData.statusCodes.forEach(function (statusItem) { 
      vm.statusList.push(statusItem); 
     }) 
    } 
} 
+0

Вы можете проверить, работает ли цикл дайджест после возврата данных? –

+0

Спасибо за быстрый ответ, мы рассмотрим это. – jwgreg

+0

@jwgreg: у нас есть аналогичная проблема, есть ли решение для этого? – fops

ответ

0

Если вы хотите ждать, что обещание решить, прежде чем отобразить вид, вы можете использовать решимости недвижимости в вашей службе $ routeProvider при настройке модуля приложения.

Там пример:

$routeProvider.when('/staff_profil/edit', { 
     templateUrl: 'app/app/assets/partials/profil-edit.html', 
     controller: 'ProfilEditController' 
     resolve: { 
      'currentUser':function(UserService){    
      return UserService.getCurrentUser(); 
     } 
    }); 

Вы должны вернуть обещание в решимости !!

В этом примере я жду, чтобы получить currentUser перед отображением моей страницы профилирования. UserService.getCurrentUser() - это обещание, созданное службой $ http в моем UserService.

Кроме того, вы можете использовать это обещание в моем контроллере ProfilEditController, введя «currentUser» в мой контроллер, например, если это услуга, а затем вы можете использовать currentUser.name в своем контроллере и просмотреть его.

Надеюсь, это поможет!

Смежные вопросы