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

查看:117
本文介绍了AngularJS指令$ 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-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天全站免登陆