角度.js:使用事件触发控制器中的操作可能会导致内存泄漏

angular.js: using events to trigger actions in controllers might cause memory leak

本文关键字:操作 泄漏 内存 js 事件 控制器 角度      更新时间:2023-09-26

我的应用程序结构如下:- 带有搜索框和按钮的静态标头- 标题中的菜单,可在视图之间切换- 在此之下,一个带有 ng 视图的div;视图通过路由提供程序在菜单单击时切换

当用户单击标头中的搜索按钮时,所有视图控制器(通过 routeProvider 分配)都应从共享服务加载一些数据。我使用事件实现了这一点。在我的搜索表单控制器中:

$scope.search = function () {
        DataStore.load($scope.searchFormState.someSearchParam, $scope.searchFormState.anotherSearchParam);
        $scope.$emit('searchForm:search');
    }

在我的控制器中,我侦听该事件并加载一些数据:

$scope.systemListener = $rootScope.$on('searchForm:search', function () {
        DataStore.promises.somePromise.then(function () {
            $scope.myDataArray = DataStore.data.dataArrayFromService;
        });
    });

然后,在我的控制器中,我侦听销毁事件:

    $scope.$on('$destroy', function () {
        $scope.systemListener();
    });

一切正常,但是当我在菜单中单击时,我注意到我的 js 堆增长很快。我怀疑某处有内存泄漏。它是否与我的控制器没有正确垃圾回收的范围有关?我是否必须在析构函数中执行任何其他操作?

如果您的控制器中有任何观察程序,您可能希望在侦听器$destroy取消监视它们。喜欢"

var $unwatch = scope.$watch(something, somethingElse);
$scope.$on('$destroy', function () {
    $unwatch();
});

另外,我建议不要在代码中使用$scope.$$listener = [];,至少因为$$listener是angularjs的局部变量,并且它的名称可能会随着即将推出的angular版本而更改。

事实证明,内存泄漏实际上可能是Chrome开发工具中的一个错误(详细信息可以在这里找到:https://github.com/angular/angular.js/issues/4864)。在我的特殊情况下,这不再是问题,因为我的应用程序已经完全重写,内存消耗现在好多了。