AngularJS - 如何在事件触发之前等待模板加载

标签 angularjs templates asynchronous

简单地说,我的情况是我从运行阶段触发一个事件。在几个指令中,我监听此事件并执行代码。问题是在我的开发机器上,一些指令在编译指令之前通过 templateUrl 属性获取模板。因此它将错过该事件。可以使用 $locationChangeSuccess 事件重现此行为。

var myApp = angular.module('myApp', []);

myApp.directive('directiveOne', function(){
    return {
        templateUrl: '/some/url.html',
        controller: function($rootScope){
            $rootScope.$on('$locationChangeSuccess', function(){
                console.log('Directive one callback');
            });
        }
    }
});

myApp.directive('directiveTwo', function(){
    return {
        template: '<div></div>',
        controller: function($rootScope){
            $rootScope.$on('$locationChangeSuccess', function(){
                console.log('Directive two callback');
            });
        }
    }
});

在此代码中,您将仅看到记录的第二条日志消息,而我希望这两个指令都记录一条消息。

如何解决这个问题?我知道我可以进行构建,将模板添加到 $templateCache,但这是我的开发计算机,我不想每次都进行构建。

最佳答案

要理解这个问题,您需要了解 Angular 指令的生命周期 ui-router 的架构.

问题是templatetemplateUrl Angular 的指令。是什么让这更有趣,你正在听$locationChangeSuccess在指令的 Controller 函数中。

所以答案是因为指令加载了它的 templateUrl 异步。这意味着 Angular 不会等待 templateUrl 完全加载(因为如果这样做,它将停止整个引导过程)。因此它继续遍历 DOM 节点,并继续在管道中执行它应该执行的操作。这当然包括加载 Controller 、触发事件、进入特定状态等。

现在如果广播$locationChangeSuccess在指令完全加载之前触发,它将错过这个特定事件,因此,您将错过 console.log

但是,如果有新的$locationChangeSuccess加载指令之后再次发生(包括完成获取 templateUrl、实例化其自己的作用域等),那么是的,您的控制台日志应该再次捕获它。

我相信你的例子,有$locationChangeSuccess仅发生一次,即在应用程序初始加载期间实例化 url。如果你真的强制另一个$locationChangeSuccess加载 DOM 后,您的第一个指令将能够再次捕获该广播事件。

同样的道理,为什么 template = "<div></div>"会起作用是因为该指令不需要异步获取它,因此当场编译,并且 DOM 在 $locationChangeSuccess 之前渲染。事件,并且能够控制台记录消息。

为了证明我的答案,我创建了一个 plnkr 。我正在使用$stateChangeSuccess在 plnkr 中,但你明白了要点。在这里,我手动触发另一个 stateChange通过单击按钮,这发生在加载指令之后。瞧,它捕捉到了广播!

TLDR:templateUrl异步取, catch locationChangeSuccess的车已经晚了.

希望这有帮助。

关于AngularJS - 如何在事件触发之前等待模板加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32720058/

相关文章:

css - 如何从 bower 组件加载 css 文件

javascript - angularJS全局过滤模块

javascript - 如何锁定由nodejs中的多个异步方法共享的对象?

angularjs - 添加具有一个复杂条件的 ng-class 的最佳方法是什么

angularjs - Angular 直接将 $scope 参数从 View 发送到服务或工厂

c++ - 如何在函数typedef中使用result_of

C++ 在模板中重载 operator=

c++ - 基本模板链表

php - 带有 FPM 的 PHP7 上的异步/线程

java - 方法内出现 AsyncCallback 的 GWT Java 错误