为什么Directive的链接功能在$ timeout之后运行

时间:2018-04-10 15:10:09

标签: angularjs timeout angular-directive

为什么$ timeout在指令渲染之前运行。这是我的指示

class B {
    /**
     * @param {A} aInstance - The instance of A.
     */
    constructor(AInstance) {
        this.a = AInstance;
    }
}

这是我控制器上的代码

angular.module('directiveTestModule').directive('popupMessage', ['$filter', 'crudService', 'serviceConfiguration', '$rootScope', '$timeout','$parse',
    function ($filter, crudService, serviceConfiguration, $rootScope, $timeout, $parse) {
        return {
            restrict: 'E',
            replace: true,
            scope: { instance:'=instance',  options: '=options' },
            replace: true,
            templateUrl: 'Scripts/app/shared/popupMessage/popupMessageView.html',
            controller: function ($scope, $element) {

            },
            link: function ($scope, $element, attr) {
                //$scope.instance = $parse(attr['popupMessage'])($scope) || {};
                $scope.instance = {};
                $scope.instance.showMessage = function () {
                    alert($scope.options.name)
                }
            }
        }
    }]);

这是html代码

$timeout(function () {
                $scope.instancePopUp.showMessage()
            }, 0)

有时,超时功能在指令的链接功能之前运行。只要我知道超时应该在所有指令初始化后运行,我错了吗?有没有办法确保指令在控制器$ timeout之前运行?

2 个答案:

答案 0 :(得分:0)

问题出现在你的指令的第一次加载中,模板没有被加载,加载它需要一些时间,并且不能保证你的超时运行。

您可以在模块运行

中预加载指令模板
angular.module('directiveTestModule').run(function ($templateCache, $http) {
        $http.get('Scripts/app/shared/popupMessage/popupMessageView.html', { cache: $templateCache });
});

这会预加载您的指令模板,这意味着您的链接功能在控制器之后运行而无需等待。

另一种解决方案是将超时逻辑从控制器移动到链接功能。

答案 1 :(得分:0)

在指令中,控制器总是在链接功能之前加载。

指令功能按以下顺序加载:

compile function
controller
pre-link function
post-link function

有关详细信息,请参阅In which order the directive functions are executed?

使用$timeoutcode smell,这是一个更大问题的症状。

考虑使用保证在此控制器的元素及其子元素已链接后调用的$postLink() Life-cycle hook

来自文档:

  

指令控制器可以提供AngularJS在指令生命周期中的点调用的以下方法:

     
      
  • $postLink() - 在此控制器的元素及其子元素已被链接之后调用。与post-link函数类似,此钩子可用于设置DOM事件处理程序并执行直接DOM操作。请注意,包含templateUrl指令的子元素将不会被编译和链接,因为它们正在等待其模板异步加载,并且它们自己的编译和链接已暂停,直到发生这种情况。
  •   
     

— AngularJS Comprehensive Directive API - Life-Cycle Hooks