AngularJS 指令 $destroy [英] AngularJS directive $destroy

查看:33
本文介绍了AngularJS 指令 $destroy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 ng-view 的 Angular 应用程序设置.在一个视图中,除了视图本身之外,该视图中还有一个动态加载的组件.这个组件是一个指令,它基本上编译内容,因此内容可以进一步与其他指令(它是)挂钩.该组件内的内容使用 $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-viewviewer 的内容.我遇到的问题是内存泄漏,其中 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆