我创建了一个指令,它绑定到链接函数中的$stateChangeSuccess
个事件:
module.exports = angular.module("titlePanel", [])
.directive("titlePanel", titlePanel);
function titlePanel($state, $rootScope, $parse, $interpolate) {
return {
restrict: "E",
replace: false,
scope: true,
templateUrl: template,
link: function(scope, element, attrs) {
// some actions
// ...
$rootScope.$on("$stateChangeSuccess", function(){
console.log("State change success happened on titlePanel");
});
}
}
此指令仅用于我网站的某些页面。令我惊讶的是,当我从包含该指令实例的状态转换到不再包含它的状态时,指令仍然响应$stateChangeSuccess
事件并执行console.log()
。
我相信,在转移到特定状态时,我误解了事件的时间顺序(我使用ui-router
)。我认为如下:
link
链接功能我可能在某处错了。你能描述正确的事件顺序吗?
答案 0 :(得分:2)
一旦指令不再在DOM中表示,它们就会被销毁。 (如果它们不可见,它们会持续存在,因此ng-show=false
会隐藏但不会破坏指令; ng-if=false
会将其销毁。)
可是:
$rootScope.$on("$stateChangeSuccess", function(){
console.log("State change success happened on titlePanel");
});
这会将事件附加到rootScope
,这在应用程序的整个生命周期中都会持续存在,即使在指令消失之后也是如此。
您可以通过在指令的'destroy'方法上显式分离事件来阻止这种情况:
var unbinder = $rootScope.$on("$stateChangeSuccess", function() {
console.log("State change success happened on titlePanel");
});
scope.$on('$destroy', function() {
unbinder();
});
...或者更好的是,通过将事件附加到指令的范围而不是根范围,因此它将自动清理。 (通常不好的做法是在不是绝对必要时避免使用根作用域:而是将事件绑定到它们所属的指令,或者绑定到专门用于此目的的共享工厂或服务。)