基于角度组件的方法并在Router中使用resolve

时间:2015-12-02 14:05:19

标签: javascript angularjs

所以我正在使用基于组件的角度方法,假设我有一个名为<home></home>;的指令

import template from  './home.html';
import controller from './home.controller.js';

angular.module('myApp')
   .directive('home', homeDirective);

let homeDirective = () => {
    return {
        restrict: 'E',
        template, 
        controller,
        controllerAs: 'vm',
        bindToController: true
    };
};

现在,我可以在路由中使用组件<home></home>,如下所示:

angular.module('myApp')
    .config(($routeProvider) => {
        $routeProvider.when('/', {
            template: '<home></home>'
        })
    })

我真的很喜欢这种方法,但是使用“旧”方法我习惯在我的routeconfig中使用“resolve”来仅在解析了promise时呈现组件:

angular.module('myApp')
    .config(($routeProvider) => {
        $routeProvider.when('/', {
            templateUrl: './home.html',
            controller: './home.controller.js',
            resolve: {
            message: function(messageService){
                return messageService.getMessage();
            }
        })
    })

问题

如何在角度中使用基于组件的方法的解析? AAJ

3 个答案:

答案 0 :(得分:16)

有一个封闭的问题:support resolve option for directives

结论是他们不希望任意指令被异步加载,因为它会导致过多的闪烁。

  

好消息是,Angular 2以一种有凝聚力的方式在DI层支持这个(以及更多),并且不会引入大量额外的复杂性。

在Angular 1.x中,您可以将指令归因于要从中获取消息的一些信息,并处理控制器中的异步加载。这样你就可以展示一些不错的装载机屏幕。

angular.module('myApp')
    .config(($routeProvider) => {
        $routeProvider.when('/', {
            template: '<home my-datasource="feed1"></home>'
        }).when('/other', {
            template: '<home my-datasource="feed2"></home>'
        })
    })
    .factory('DataSources', (messageService) => {
        return {
            feed1: messageService.getMessage,
            feed2: messageService.getError
        };
    });

或者,如果您希望message来自同一来源,则可以将messageService.getMessage().then(...)刻录到您的控制器中。

如果你不希望指令在promises解决之前完全可见,你可以引入一个最初设置为false的作用域变量,然后在解析时将其设置为true,例如:

app.controller('HomeController', ($scope, messageService) => {
   $scope.loaded = false;
   messageService.getMessage().then(message => {
       ...
       $scope.loaded = true;
   });
   ...
});

并隐藏指令,直到在根元素处加载ng-if="loaded"。是的,用户代码太多了,但你至少可以控制一切。

答案 1 :(得分:1)

事实证明,角度$ routeProvider将已解析的本地传递给$ routeChangeSuccess事件(nextRoute.locals)。因此,您可以创建一个侦听路由更改并公开本地的服务:

angular.module('myApp', ['ngRoute'])
.factory('$routeLocals', function($rootScope) {
  var locals = {};
  $rootScope.$on('$routeChangeSuccess', function(_, newRoute) {
    angular.copy(newRoute.locals, locals);
  });
  return locals;
})
.run(function($routeLocals) {});

然后你可以将$ routeLocals注入你的指令并使用它们。

示例:http://codepen.io/fbcouch/pen/eJYLBe

https://github.com/angular/angular.js/blob/master/src/ngRoute/route.js#L614

答案 2 :(得分:1)

在Angular 1.x中,当一些数据来自ajax我的指令绑定('=')时,我会在指令中看到这个绑定,我没有正确地呈现指令。我检查了很多stackoverflow主题和博客,以及他们写的关于数据绑定和观看的所有内容,但它对我没有帮助,我亲眼看到有时指令未呈现但数据来了。

在这种情况下,指令父控制器中只有resolve可以帮助我,因为在其他情况下,它看起来像未定义的行为。我从我的指令登录,数据设置正常,但指令未呈现!(在简单的情况下,我不使用ng-if或ng-show来隐藏它)。

您可以阅读更多here