Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 带有element.empty()的Angular JS作用域泄漏_Angularjs_Memory Leaks - Fatal编程技术网

Angularjs 带有element.empty()的Angular JS作用域泄漏

Angularjs 带有element.empty()的Angular JS作用域泄漏,angularjs,memory-leaks,Angularjs,Memory Leaks,在Angular.JS项目中,我有一个带有复杂模板的指令,它被实例化了数千次(在网格中) 出于性能原因,我不得不将模板拆分为多个子模板。根据指令的范围值组合,我选择一个子模板 性能增益是真实的(在非常大的网格上大于100),但在某些情况下(当子模板包含ng repeat指令时),Angular正在调用在已删除DOM元素范围内声明的函数 我将问题简化为以下最小代码: angular.module('myApp', []).directive('myDirective', ['$compile',

在Angular.JS项目中,我有一个带有复杂模板的指令,它被实例化了数千次(在网格中)

出于性能原因,我不得不将模板拆分为多个子模板。根据指令的范围值组合,我选择一个子模板

性能增益是真实的(在非常大的网格上大于100),但在某些情况下(当子模板包含ng repeat指令时),Angular正在调用在已删除DOM元素范围内声明的函数

我将问题简化为以下最小代码:

angular.module('myApp', []).directive('myDirective', ['$compile', '$log', function ($compile, $log) {
  function display(scopeId, x) {
    $log.log('func called with', x, 'in scope', scopeId);

    return x;
  }

  return {
    scope: true,
    link: function (scope, element) {
      scope.array = [1, 2, 3];
      scope.display = display;

      scope.$watch(function () {
        return scope.abc;
      }, function (newValue) {
        var newContent = angular.element('<div ng-repeat="item in array">{{display($id, item)}}</div>');

        element.empty();

        element.append($compile(newContent)(scope))
      });
    }
  };
}]);
谢谢。

回应我自己

观察角度源
element.empty()
调用jQuery.empty()等等

删除DOM元素时,将删除对角度范围的引用,但该范围仍在其父范围的子范围的链接列表中


因此需要子作用域。

您应该执行
element.remove()
,这也会删除作用域。
element.remove()
不会删除作用域。需要显式销毁作用域。
empty()
不会删除元素。。。它删除了它的内部htmlSo,因此拥有
childScope
是唯一的解决方案吗?
angular.module('myApp', []).directive('myDirective', ['$compile', '$log', function ($compile, $log) {
  var childScope;

  function display(scopeId, x) {
    $log.log('func called with', x, 'in scope', scopeId);

    return x;
  }

  return {
    scope: true,
    link: function (scope, element) {
      scope.array = [1, 2, 3];
      scope.display = display;

      scope.$watch(function () {
        return scope.abc;
      }, function (newValue) {
        element.empty();

        if (childScope) {
            childScope.$destroy();
        }

        element.append(angular.element('<div ng-repeat="item in array">{{display($id, item)}}</div>'));

        childScope = scope.$new();

        $compile(element.contents())(childScope);
      });
    }
  };
}]);