加载视图配置

时间:2016-03-04 11:15:59

标签: javascript angularjs angular-routing

我想做这样的事情:

app.config(function($routeProvider){
$routeProvider.when('products/list', {
    controller: 'ProductListCtrl',
    templateUrl : 'products/list/view.html',
    resolve : { data : function(){
        ...
    },
    loadingTemplateUrl : 'general/loader.html'
}
});

我希望将加载页面放在不同的视图中。

这将使每个页面的视图和控制器中的代码更清晰(没有< ... ng-include ng-show =" loading" ...>)。这也意味着我不需要$ scope。$观察数据的变化。是否有一个干净的解决方案来执行类似的操作(不一定在.config方法中)或替代库来执行此操作?

2 个答案:

答案 0 :(得分:0)

假设您想在解析数据时显示所有状态转换的一般模板,我的建议是监听路由库触发的事件。这允许使用一个中心点来处理所有状态转换,而不是污染路由配置(我认为这不是那么容易)。

请在the angular router docs

查看$routeChangeStart$routeChangeSuccess以及$routeChangeError的文档

答案 1 :(得分:0)

也许某人可能对我所做的事感兴趣:我创建了一个新服务和一个新的视图指令。看起来似乎很多工作,但这样做比我想象的要容易得多。新服务使我能够将主视图与加载视图分开,我可以在应用程序的所有页面中重用该视图。我还提供了配置错误模板URL和错误控制器的可能性,用于加载失败时。

Angular $ injector,$ templateRequest和$ controller服务完成了大部分工作。我只需要将一个依赖于这些服务的指令连接到正确的事件($ locationChangeSuccess),并将其从解析对象的函数中检索(使用$ q.all)。此连接在路由服务中完成。该服务选择正确的模板url和comtroller,并将其传递给指令以进行处理。

缩短版本(省略了getCurrentConfig方法):

RouteService:

(function () {
    'use strict';

// provider: 

    angular.module('pikcachu')
        .provider('pikaRouteService', [function () {

        var routeConfigArray;
        var otherwiseRouteConfig;
        //configuration methods
        this.when = function (url, routeConfig){
            routeConfigArray.push({url: url, routeConfig: routeConfig});
            return this; 
        }
        this.otherwise = function(routeConfig){
            otherwiseRouteConfig = routeConfig;
            return this;
        }
        // service factory:
        this.$get = ['$rootScope', '$location', '$q', '$injector', '$templateRequest', 
            function ($rootScope, $location, $q, $injector, $templateRequest) {
                function RouteService() {
                    this.setViewDirectiveUpdateFn = function(){ /*...*/ }

                    function init(){
                        $rootScope.$on('$locationChangeSuccess', onLocationChangeSuccess);
                    }

                    function onLocationChangeSuccess(){
                        // get the configuration based on the current url
                        // getCurrentConfig is a long function, because it involves parsing the templateUrl string parameters, so it's left out for brevity
                        var currentConfig = getCurrentConfig($location.url());
                        if(currentConfig.resolve !== undefined){
                            // update view directive to display loading view
                        viewDirectiveUpdateFn(currentConfig.loadingTemplateUrl, currentConfig.loadingController);
                            // resolve
                            var promises = [];
                            var resolveKeys = [];
                            for(var resolveKey in currentConfig.resolve){
                               resolveKeys.push(resolveKey);
                               promises.push($injector.invoke(resolve[resolveKey]));
                            }
                            $q.all(promises).then(resolveSuccess, resolveError);
                            function resolveSucces(resolutionArray){
                               // put resolve results in an object
                               var resolutionObject = {};
                               for(var i = 0; i< promises.length;++i){
                                  resolved[resolveKeys[i]] = resolutionArray[i];
                               }
                                 viewDirectiveUpdateFn(currentConfig.errorTemplateUrl, currentConfig.errorController);
                            }
                            function resolveError(){
                                viewDirectiveUpdateFn(currentConfig.errorTemplateUrl, currentConfig.errorController);
                            }
                        }
                    }

                    init();
                }
                return new RouteService();
            }]
    })();

查看指令

(function () {
    'use strict';
    angular.module('pikachu')
        .directive('pikaView', ['$templateRequest', '$compile', '$controller', 'pikaRouteService', function ($templateRequest, $compile, $controller, pikaRouteService) {

            return function (scope, jQdirective, attrs) {
                var viewScope;

                function init() {
                    pikaRouteService.listen(updateView);
                }

                function updateView(templateUrl, controllerName, resolved) {
                    if(viewScope!== undefined){
                        viewScope.$destroy();
                    }
                    viewScope = scope.$new();
                    viewScope.resolved = resolved;
                    var controller = $controller(controllerName, { $scope: viewScope });
                    $templateRequest(templateUrl).then(onTemplateLoaded);
                    function onTemplateLoaded(template, newScope) {
                        jQdirective.empty();
                        var compiledTemplate = $compile(template)(newScope);
                        jQdirective.append(compiledTemplate);
                    }
                }

                init();
            };
        }
    ]);
})();