为什么$timeout在指令渲染之前运行。这是我的指示
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)
}
}
}
}]);
这是我控制器上的代码
$timeout(function () {
$scope.instancePopUp.showMessage()
}, 0)
这是 html 代码
<popup-message instance="instancePopUp" options="optionsPopup"></popup-message>
有时,超时函数在指令的链接函数之前运行。只要我知道在所有指令初始化后应该运行超时,我错了吗?有没有办法确保指令在控制器上$timeout之前运行?
在指令中,控制器总是在链接函数之前加载。
指令函数按以下顺序加载:
compile function
controller
pre-link function
post-link function
有关更多信息,请参阅指令函数的执行顺序?
使用$timeout
是一种代码气味,是更大问题的症状。
考虑使用$postLink()
生命周期挂钩,该挂钩保证在此控制器的元素及其子元素链接后调用。
从文档中:
指令控制器可以提供以下方法,这些方法由 AngularJS 在指令生命周期的点调用:
$postLink()
- 在此控制器的元素及其子元素已链接后调用。与 post-link 函数类似,此钩子可用于设置 DOM 事件处理程序并执行直接的 DOM 操作。请注意,包含 templateUrl 指令的子元素不会进行编译和链接,因为它们正在等待其模板异步加载,并且它们自己的编译和链接已挂起,直到发生这种情况。— AngularJS Comprehensive Directive API - Life-Cycle Hooks
问题出在指令的第一次加载中,模板未加载,加载它需要一些时间,并且无法保证超时在它之后运行。
您可以在模块运行中预加载指令模板
angular.module('directiveTestModule').run(function ($templateCache, $http) {
$http.get('Scripts/app/shared/popupMessage/popupMessageView.html', { cache: $templateCache });
});
这会预加载您的指令模板,这意味着您的链接函数在控制器之后运行而无需等待。
另一种解决方案是将超时逻辑从控制器移动到链路功能。