Angular + Breeze项目中查找客户端缓存的问题

时间:2014-01-24 16:20:45

标签: angularjs breeze clientside-caching

我们有一个基于John Papa使用Angular,Breeze和UI-Bootstrap的HotTowel SPA的项目。

我们正在使用客户端缓存来加载来自SQL Lookup表的Dropdown。视图在缓存数据之前加载,导致视图首次加载时出现空的下拉。如果我们刷新视图,那么下降然后填充。我们意识到这是排序和路由问题,但无法弄清楚如何使其工作。

问题似乎集中在承诺的使用以及如何识别它们何时成功返回。我们使用prime函数在启动时从数据库加载缓存数据,但在getActionDomain()函数中访问数据之前加载搜索视图。

我们很感激任何指示或想法。

谢谢,

JG

app.js中的app.run是起点

(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;
        }
    }]);

})();

prime函数可以在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;
    }

}

在search.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);
        })
    }
}

1 个答案:

答案 0 :(得分:0)

如果要在显示视图之前等待承诺得到解决,则可以在配置应用程序模块时使用服务$ routeProvider中的 resolve 属性。

有一个例子:

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

你必须在决心中回报一个承诺!!

在此示例中,我等待获取currentUser,然后再显示我的profil-edit页面。 UserService.getCurrentUser()是由我的UserService中的$ http服务创建的承诺。

此外,您可以在我的控制器ProfilEditController中使用此promise promise,通过在我的控制器中输入'currentUser',就好像它是一个服务然后你可以使用currentUser.name 在您的控制器和视图中。

我希望这会对你有所帮助!