【问题标题】:Clearing an interval when an element housing an angular directive is removed移除包含角度指令的元素时清除间隔
【发布时间】:2013-10-10 00:14:25
【问题描述】:

我已经构建了一个简单的指令,它添加了一个基于 javascript 的加载动画。它使用window.setInterval() 循环运行。这很好用,但是当加载完成时,我使用ngSwitch 交换我的内容,这会从页面中删除包含加载指令属性的元素。

理想情况下,我想注意这种变化并清除我的间隔,这样动画计算就不会仍在后台运行。我尝试观看一个自定义函数来评估页面上元素的存在。我知道该功能可以检测到这一点,但似乎时间是一个问题——据我所知,当指令属性的元素离开页面时,$watch 本身被清除。因此,我的$watch'ed 表达式永远不会检测到更改,也永远不会调用其清除动画间隔函数的回调。

有处理这种情况的推荐模式吗?

我模板中的相关sn-p:

<div ng-switch on="dataStatus">

  <div ng-switch-when="loading">
    <div loading-spinner></div>
  </div>

  <div ng-switch-when="haveData">
    <!-- data dependent on content we were loading -->
  </div>

</div>

我的指令的简化版:

myModule.directive('loadingSpinner', function () {
  var updateMySweetAnimation = function (element) { /* ... */ };
  return {
    link: function (scope, iElement, iAttrs) {
      var spinner = window.setInterval(function () {
        updateMySweetAnimation(iElement);
      }, 100);

      scope.$watch(function () {
        return $(document).find(iElement).length;
      }, function (present) {
        if (!present) {
          clearInterval(spinner);
        }
      });
    }
  };
});

【问题讨论】:

    标签: angularjs directive ng-switch


    【解决方案1】:

    当元素被ng-switch从页面中清除时,会发生两件事:

    1. ng-switch-when 创建的作用域(带有您的指令的元素)被销毁。这会杀死您的$watch 并在您可以使用scope.$on('$destroy', ...) 观看的范围内生成$destroy 事件。

    2. 元素已从 DOM 中移除。这会生成一个单独的销毁事件,您可以使用 iElement.on('$destroy', ...) 观看该事件。

    它们应该按这个顺序发生,查看最新的稳定版本 (1.0.8 - https://github.com/angular/angular.js/blob/v1.0.8/src/ng/directive/ngSwitch.js),因此当从 DOM 中删除元素时,您的范围和手表应该始终处于死状态。

    您可以通过从定义ng-switch 的外部范围观察来避免此问题。或者您可以观看dataStatus,与您的ng-switch 中的条件相同,而不是寻找ng-switch 的结果来查看您的条件变化。

    这两种方法都可能有效,但实际上您需要做的,实际上是正常的模式,就是观察$destroy 事件之一并清理那里的所有内容。由于间隔感觉与视图比模型更相关,因此我将使用 DOM 事件并将您的 $watch 替换为

    iElement.on('$destroy', function(){
        clearInterval(spinner);
    });
    

    【讨论】:

    • 谢谢@Andyrooger,这正是我想要的。因为我打算让我的指令非常可重用,所以我不想将它耦合到它在此实例中获得的特定父作用域上的任何模型,所以我将为 DOM 事件设置一个处理程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    相关资源
    最近更新 更多