在Angular.JS項目中,我有一個指令與一個複雜的模板,實例化數千次(在網格中)。Angular JS範圍泄漏與element.empty()
由於性能原因,我不得不在多個子模板中拆分模板。根據指令的範圍值組合,我選擇一個子模板。
性能增益是真實的(在非常大的網格上大於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))
});
}
};
}]);
你可以在這裏進行測試:https://jsfiddle.net/yss4yskm/6/
每次元素被替換(當你點擊複選框),通過創建的每個範圍ng-repeat被泄露:作用域繼續登錄到瀏覽器控制檯,Batarang也顯示泄漏的作用域。
不應該element.empty()
刪除所有的子範圍?
爲什麼問題只發生在ng-repeat指令中?
我可以通過創建子範圍並在需要時銷燬(https://jsfiddle.net/yss4yskm/9/)來避免泄漏,但我不應該這樣做。
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);
});
}
};
}]);
謝謝。
你應該做'element.remove()'它也會刪除範圍.. –
'element.remove()'不會刪除範圍。範圍需要被明確銷燬。 –