0

我构建了一个简单的指令,添加了一个基于 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);
        }
      });
    }
  };
});
4

1 回答 1

2

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

  1. 为您创建的范围ng-switch-when,即带有您的指令的元素,将被销毁。这会杀死您并在您可以观看的范围内$watch生成一个事件。$destroyscope.$on('$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);
});
于 2013-10-10T00:32:51.243 回答