简体   繁体   English

AngularJS:以正确的顺序从控制器和指令链接执行$ timeout回调

[英]Angularjs: execute $timeout callback from controller and directive link in the right order

I have this simple app with a custom directive and it's controller: 我有一个带有自定义指令的简单应用,它是控制器:

angular.module('app', [])
.directive('customDir', function($timeout){
  return {
        restrict: 'E',
        template: 'custom dir template',
        controller: 'customDirCtrl',
        link: function () {
          $timeout(function(){
            console.log('link');
          });
        }
  }
})
.controller('customDirCtrl', function($timeout) {
    $timeout(function(){
            console.log('ctrl');
          }).then(function(){
    });
});

Both the directive's link function and controller contains a timeout callback which in the case above will be executed in this order: ctrl's function then link's function. 指令的链接函数和控制器都包含超时回调,在上述情况下,将按以下顺序执行:ctrl的函数,然后是链接的函数。 See here: https://codepen.io/neptune01/pen/EoxgvV 看到这里: https : //codepen.io/neptune01/pen/EoxgvV

What I need is to ensure that the timeout callback in the controller is executed after the one from the directive's link. 我需要确保在指令链接中的超时回调之后执行控制器中的超时回调。 How do I do that? 我怎么做?

The initialization of the directive is composed of these 4 events in the same order: 指令初始化由这4个事件以相同的顺序组成:

  1. compile 编译
  2. controller 控制者
  3. pre-link 预链接
  4. post-link 链接后

So, you need to move that timeout to the compile function instead to get it executed prior to controller initialization. 因此,您需要将该超时移至compile函数,以使其在控制器初始化之前执行。

Probably if you have some event in directive, you can bind that element and on change, you can do timeout. 可能如果指令中有某些事件,则可以绑定该元素,并在更改时可以执行超时。 If you have variable you can use $watch or if you have some other event you can use $on and $emit to emit that event to controller. 如果您有变量,则可以使用$ watch;如果您有其他事件,则可以使用$ on和$ emit将该事件发送给控制器。 It's not pretty solution, but it can work. 这不是一个很好的解决方案,但它可以工作。

You can broadcast from the link when the timeout is done 超时完成后,您可以从链接中广播

angular.module('app', [])
.directive('customDir', function($timeout){
  return {
    restrict: 'E',
    template: 'custom dir template',
    controller: 'customDirCtrl',
    link: function ($scope) {
      $timeout(function(){
        console.log('link');
        $scope.$broadcast('linkTimeoutDone')            
      });
    }
 }
})
.controller('customDirCtrl', function($scope) {
  $scope.$on('linkTimeoutDone', function() {
    console.log('ctrl');
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM