销毁指令时是否需要销毁本地控制器变量?
Do I need to destroy local controller variables when directive is destroyed?
我最近写了很多 Angular 指令,并且一直在阅读有关在销毁指令时必须手动删除您在指令中创建的内容的内容。不过还是有点不清楚。
我知道放置在 $scope 上的任何东西都会被销毁,但是在指令的控制器中创建的局部变量、数组、函数等呢?
这是我的应用程序中的一些示例代码
angular.module('myModule').controller('s4pFileUploadCtrl', function($scope, $element, $attrs, FileUploader){
var self = this;
self.uploader = new FileUploader({
settings: {}
});
// Elsewhere in the controller
var reader = new FileReader();
reader.onload = onLoadFile;
function onLoadFile(event) {
var img = new Image();
img.onload = onLoadImage;
}
});
这是一个设计精简的函数,但我需要在 $scope destroy 事件上删除上传器吗?我需要对 FileReader 及其关联的 onLoadFile 事件执行任何操作吗?
如有任何帮助,我们将不胜感激。我读过很多关于清理指令的文章,但其中 none 提到了这样的事情。
当 $scope.$destroy() 被执行时,它将删除所有通过 $on 在该 $scope 上注册的监听器。
它不会删除 DOM 个元素或任何附加的事件处理程序。
如果在元素上调用 element.remove() 则它的所有子元素将从 DOM 一起删除,所有事件处理程序都将通过 element.on 附加,但它不会销毁与元素关联的 $scope。
这里 a great article 提供了一些关于 javascript 内存管理和垃圾回收的背景知识。基本上,它的工作原理是这样的...
Javascript内存管理-垃圾收集器
对象创建时分配内存:
var o = {iThink: 'thereforeIAm'}; // memory allocated for an object and a string
然后您可以 console.log(o.iThink)
并且 'thereforeIAm'
将从其在内存中的位置读取并打印到控制台。
如果你想创建一个新的字符串并且丢失了 {iThink: 'thereforeIAm'}
对象的 需要 ,你可以决定覆盖 o
而不是引入一个新变量例如:
o = 'helloImANewString';
幸运的是,引用(或缺少引用)会在内部向 javascript 的垃圾收集器发送一条明确的消息,说明是否应保留分配或释放一段(有限)内存以执行其他任务。在这种情况下,不会保留对先前为 {iThink: 'thereforeIAm'}
分配的对象和字符串的引用,结果可能会释放相应的内存(即 "garbage-collected")。
重要的是,请注意垃圾回收发生在内部。您不必为此编写任何代码。您需要关心的只是 o
的值,垃圾收集器可以 推断需要 ,或多或少, 来自剩余的引用 .
Angular 内存管理 - $scope.$destroy
不幸的是,$scope
删除相关的清理任务 无法由 javascript 垃圾收集器 仅根据参考 推断 =74=];需要额外的代码。
那是因为 $scope 对象体现了一个比任何 ol' javascript 对象都复杂的概念。特别是,当您的应用程序中某个 $scope
对象没有用处时,对于之前在 $scope.$watch
方法并且没有用 也必须为 "children" $scope
对象保留 。 javascript 垃圾收集器无法从简单的引用删除中推断出这种关系,例如:
$scope = null; // $scope object will be garbage collected, but nothing else
换句话说,垃圾收集器必须被告知要做什么,这正是 $scope.$destroy method 所做的。特别注意这些行:
$scope.$parent = $scope.$$nextSibling = $scope.$$prevSibling = $scope.$$childHead =
$scope.$$childTail = $scope.$root = $scope.$$watchers = null;
现在回答你的问题
I know that anything placed on $scope is destroyed, but what about local variables, arrays, functions etc created in a directive's controller?
是的,但不是直接通过 $destroy 方法。
调用函数时,为内部作用域对象分配的内存将仅在调用生命周期结束后仍保留引用的范围内保持分配。
在你的控制器的例子中,事实上,在控制器功能是 运行 之后根本没有对 reader
的引用,无论 $scope
是否是 $destroy
'编辑。但是,即使您确实像 uploader
那样将它附加到 $scope
,唯一剩下的引用来自对 $scope 的这种附加。因此,对 $scope.$destroy()
的任何调用都会删除对 uploader
的最后引用(通过删除对 $scope
的任何引用)并使其符合 javascript 垃圾收集的条件。
我最近写了很多 Angular 指令,并且一直在阅读有关在销毁指令时必须手动删除您在指令中创建的内容的内容。不过还是有点不清楚。
我知道放置在 $scope 上的任何东西都会被销毁,但是在指令的控制器中创建的局部变量、数组、函数等呢?
这是我的应用程序中的一些示例代码
angular.module('myModule').controller('s4pFileUploadCtrl', function($scope, $element, $attrs, FileUploader){
var self = this;
self.uploader = new FileUploader({
settings: {}
});
// Elsewhere in the controller
var reader = new FileReader();
reader.onload = onLoadFile;
function onLoadFile(event) {
var img = new Image();
img.onload = onLoadImage;
}
});
这是一个设计精简的函数,但我需要在 $scope destroy 事件上删除上传器吗?我需要对 FileReader 及其关联的 onLoadFile 事件执行任何操作吗?
如有任何帮助,我们将不胜感激。我读过很多关于清理指令的文章,但其中 none 提到了这样的事情。
当 $scope.$destroy() 被执行时,它将删除所有通过 $on 在该 $scope 上注册的监听器。
它不会删除 DOM 个元素或任何附加的事件处理程序。
如果在元素上调用 element.remove() 则它的所有子元素将从 DOM 一起删除,所有事件处理程序都将通过 element.on 附加,但它不会销毁与元素关联的 $scope。
这里 a great article 提供了一些关于 javascript 内存管理和垃圾回收的背景知识。基本上,它的工作原理是这样的...
Javascript内存管理-垃圾收集器
对象创建时分配内存:
var o = {iThink: 'thereforeIAm'}; // memory allocated for an object and a string
然后您可以 console.log(o.iThink)
并且 'thereforeIAm'
将从其在内存中的位置读取并打印到控制台。
如果你想创建一个新的字符串并且丢失了 {iThink: 'thereforeIAm'}
对象的 需要 ,你可以决定覆盖 o
而不是引入一个新变量例如:
o = 'helloImANewString';
幸运的是,引用(或缺少引用)会在内部向 javascript 的垃圾收集器发送一条明确的消息,说明是否应保留分配或释放一段(有限)内存以执行其他任务。在这种情况下,不会保留对先前为 {iThink: 'thereforeIAm'}
分配的对象和字符串的引用,结果可能会释放相应的内存(即 "garbage-collected")。
重要的是,请注意垃圾回收发生在内部。您不必为此编写任何代码。您需要关心的只是 o
的值,垃圾收集器可以 推断需要 ,或多或少, 来自剩余的引用 .
Angular 内存管理 - $scope.$destroy
不幸的是,$scope
删除相关的清理任务 无法由 javascript 垃圾收集器 仅根据参考 推断 =74=];需要额外的代码。
那是因为 $scope 对象体现了一个比任何 ol' javascript 对象都复杂的概念。特别是,当您的应用程序中某个 $scope
对象没有用处时,对于之前在 $scope.$watch
方法并且没有用 也必须为 "children" $scope
对象保留 。 javascript 垃圾收集器无法从简单的引用删除中推断出这种关系,例如:
$scope = null; // $scope object will be garbage collected, but nothing else
换句话说,垃圾收集器必须被告知要做什么,这正是 $scope.$destroy method 所做的。特别注意这些行:
$scope.$parent = $scope.$$nextSibling = $scope.$$prevSibling = $scope.$$childHead =
$scope.$$childTail = $scope.$root = $scope.$$watchers = null;
现在回答你的问题
I know that anything placed on $scope is destroyed, but what about local variables, arrays, functions etc created in a directive's controller?
是的,但不是直接通过 $destroy 方法。
调用函数时,为内部作用域对象分配的内存将仅在调用生命周期结束后仍保留引用的范围内保持分配。
在你的控制器的例子中,事实上,在控制器功能是 运行 之后根本没有对 reader
的引用,无论 $scope
是否是 $destroy
'编辑。但是,即使您确实像 uploader
那样将它附加到 $scope
,唯一剩下的引用来自对 $scope 的这种附加。因此,对 $scope.$destroy()
的任何调用都会删除对 uploader
的最后引用(通过删除对 $scope
的任何引用)并使其符合 javascript 垃圾收集的条件。