清除容纳角度指令的元素时的间隔

时间:2013-10-10 00:14:25

标签: angularjs directive ng-switch

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

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

是否有建议的模式来处理这种情况?

我的模板中的相关摘录:

<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);
        }
      });
    }
  };
});

1 个答案:

答案 0 :(得分:2)

ng-switch从页面中清除元素时,应该发生两件事:

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

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

  3. 它们应按此顺序发生,查看最新的稳定版本(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);
    });