AngularJS指令$ destroy [英] AngularJS directive $destroy
问题描述
我使用ng-view
进行了有角度的应用设置.在一个视图中,除了视图本身之外,该视图中还有一个动态加载的组件.该组件实际上是一个编译内容的指令,因此该内容可以进一步与其他指令(实际上是)挂钩.该组件内部的内容是使用$compile(element.contents())(scope);
编译的.
I have an angular app setup with ng-view
. In one view, in addition to the view itself, there is also a component inside that view that is dynamically loaded. This component is a directive that essentially compiles the contents so the contents can be further hooked with other directives (which it is). The content inside that component is compiled using $compile(element.contents())(scope);
.
例如:
<ng-view>
<viewer doc="getDocument()">
</viewer>
</ng-view>
angular.directive('viewer', ['$compile', '$anchorScroll', function($compile, $anchorScroll) {
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
var doc = scope.$eval(attrs.doc);
if (!doc)
return ""
return doc.html;
},
function(value) {
element.html(value);
$compile(element.contents())(scope);
}
);
};
}]);
我的问题是,当我切换路由时,实际上是在切换ng-view
或viewer
的内容.我遇到的问题是内存泄漏,在viewer
内的其他指令中,钩住了事件,并且在更改路线时不进行清理.
My problem is when I switch routes, I essentially switch ng-view
or viewer
's content. The problem I'm having is a memory leak, where in other directives inside the viewer
hooks to events and do not clean up when the route is changed.
一个这样的例子如下:
angular.directive('i18n', ['$rootScope', 'LocaleService', function($rootScope, LocaleService) {
var cleanup;
return {
restrict: 'EAC',
compile: function(element, attrs) {
var originalText = element.text();
element.text(LocaleService.getTranslation(originalText, attrs.locale));
cleanup = $rootScope.$on('locale-changed', function(locale) {
element.text(LocaleService.getTranslation(originalText, attrs.locale || locale));
});
},
link: function(scope) {
scope.$on('$destroy', function() {
console.log("destroy");
cleanup();
});
}
};
}]);
我如何拥有它以便正确清理这些事件?
How do I have it so that these events are properly cleaned up?
谢谢.
推荐答案
您提供的i18n示例仅使用一次就可以使用.
The i18n example you provided would work if you only ever used it once.
我认为您不应该在compile函数中进行事件绑定.您可以改为在链接函数中完成此操作:
I don't think you should be doing the event binding inside the compile function. You can do it inside the link function instead:
angular.directive('i18n', ['$rootScope', 'LocaleService', function($rootScope, LocaleService) {
return {
restrict: 'EAC',
link: function(scope, element, attrs) {
var cleanup;
var originalText = element.text();
element.text(LocaleService.getTranslation(originalText, attrs.locale));
cleanup = $rootScope.$on('locale-changed', function(locale) {
element.text(LocaleService.getTranslation(originalText, attrs.locale || locale));
});
scope.$on('$destroy', function() {
console.log("destroy");
cleanup();
});
}
};
}]);
或者,您可以在子作用域本身上绑定事件,并在$rootScope
上使用$broadcast
触发它.这样,当范围被销毁时,事件将自动被垃圾收集:
Alternatively, you could bind the event on the child scope itself, and use $broadcast
on the $rootScope
to trigger it. That way the event will automatically be garbage collected when the scope is destroyed:
angular.directive('i18n', ['$rootScope', 'LocaleService', function($rootScope, LocaleService) {
return {
restrict: 'EAC',
link: function(scope, element, attrs) {
var originalText = element.text();
setElText();
function setElText(locale){
element.text(LocaleService.getTranslation(originalText, attrs.locale || locale));
}
scope.$on('locale-changed', setElText);
}
};
}]);
$rootScope.$broadcast('locale-change', 'en-AU');
这篇关于AngularJS指令$ destroy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!