7

我看过很多指令示例,包括AngularUI 团队的那些,它们似乎没有进行任何清理。

这是他们的 ui-date 指令中的一个示例,它创建了一个 jQuery 日期选择器。 (资源)

element.on('blur', function() { ... });

他们在元素上放置了一个事件处理程序,但他们从未解除绑定事件。我本来希望会有代码存在,例如:

var namespace = ".uiDate";

element.on('blur' + namespace, function() { ... });
element.on("$destroy" + namespace, function ()
{
   element.datepicker("destroy");      //Destroy datepicker widget
   element.off(namespace);             //Unbind events from this namespace
});

所以这让我想知道是否有什么我不明白的。在反复创建和销毁带有此指令的元素的情况下,他们所做的事情不会导致内存泄漏吗?

我错过了什么?

4

1 回答 1

6

是的,理想情况下,您应该清理任何附加到元素的事件处理程序,而不是链接到指令的元素。

例如,如果在您的指令中有一个窗口调整大小函数来修改指令的元素,您将需要在指令被销毁时删除窗口调整大小事件。

这是我必须构建的示例指令,您可以看到我必须取消绑定附加在指令范围之外的事件处理程序:

lrApp.directive('columnArrow',function($timeout){
  return {
    restrict : 'A',
    scope : {
      active : '=columnArrow'
    },
    link: function($scope, elem, attrs, controller) {
        $scope.$watch('active',function(){
          $timeout(function(){
            adjust();
          },0);
        });

        $(window).resize(adjust);

        elem.parents('.column-content').scroll(adjust);

        $scope.$on('$destroy', function () {
          elem.removeClass('hide');
          elem.parents('.column-content').unbind('scroll',adjust);
          $(window).unbind('resize',adjust);
        });

        function adjust(e) {
          if($scope.active) {
            var parentScroll = elem.parents('.column-content');
            var parent = elem.parent();
            var visible = inView(parentScroll[0],parent[0]);
            if(!visible) {
              elem.addClass('hide');
            } else {
              elem.removeClass('hide');
            }
            var offset = parent.offset();
            var w = parent.outerWidth();
            var h = (parent.outerHeight() / 2) - (elem.outerHeight() / 2);
            elem.css({'top':offset.top + h,'left':offset.left + (w + 5)});
          }
        };

    }
  }
});
于 2013-10-13T20:22:15.470 回答