为了使不同的组件能够互相通信,我在$emit
方法中使用了service
方法
服务代码:
this.triggerSelectedAction = function( actionName )
{
$rootScope.$emit('action-changed', { actionName: actionName } );
};
this.triggerSelectedProject = function( projectName )
{
$rootScope.$emit('project-changed', { projectName: projectName } );
};
this.triggerSelectedFile = function( fileName )
{
$rootScope.$emit('file-changed', { fileName: fileName } );
};
this.subscribe = function( scope, cb )
{
var eventHandler;
eventHandler = $rootScope.$on('action-changed', cb);
eventHandler = $rootScope.$on('project-changed', cb);
eventHandler = $rootScope.$on('file-changed', cb);
scope.$on( '$destroy', eventHandler );
};
现在让我们假设我从应用程序内的某个位置调用了myService.triggerSelectedAction('doSomething');
,并且在其$state
方法等待时加载了特定的$onInit
(例如toolsState)此事件发生。
toolsState控制器$onInit
代码:
myService.subscribe($scope, function eventOccured(event, data) {
if ( event.name === "action-changed" )
setEnvironment();
});
function setEnvironment() {
// Attach an event listener to the select element
document
.getElementById("design-select")
.addEventListener("change", projectSelectedEvent);
}
现在让我们说我们改变一个状态,例如转到manageState,它也等待同一事件的发生,并且具有类似的$onInit
代码,但它绑定了eventListener
到另一个元素。
管理状态控制器$onInit
代码:
myService.subscribe($scope, function eventOccured(event, data) {
if ( event.name === "action-changed" )
setEnvironment();
});
function setEnvironment() {
// Attach an event listener to the select element
document
.getElementById("manage-select")
.addEventListener("change", projectSelectedEvent);
}
在这种情况下,如果触发了该事件,则除了我在控制台中得到一个TypeError: Cannot read property 'addEventListener' of null
并使用addEventListener方法引用toolsState
控制器行的控制台外,其他所有操作均按预期进行。它抱怨说由于状态变化而找不到id
中design-select
的元素。
在我看来,$scope
的{{1}}的状态改变了,因此其toolsState
方法仍在运行。
有什么方法可以消除此错误。
答案 0 :(得分:0)
每当代码将函数或对象传递给API时,就有创建对象引用的风险,这将阻止垃圾回收。这可能会导致内存泄漏。
$on
方法返回一个可用于取消绑定事件处理程序的函数:
this.subscribe = function( scope, cb )
{
var deRegister = {};
deRegister.ActionChanged = $rootScope.$on('action-changed', cb);
deRegister.ProjectChanged = $rootScope.$on('project-changed', cb);
deRegister.FileChanged = $rootScope.$on('file-changed', cb);
scope.$on( '$destroy', function() {
deRegister.ActionChanged();
deRegister.ProjectChanged();
deRegister.FileChanged();
deRegister = null; //release deRegister object
scope = null; //release scope reference
cb = null; //release callback function reference
));
};
除了注销事件处理程序外,代码还需要释放所有创建的对象引用。