Javascript AngularJS$emit在添加要注销的代码后不会触发事件

Javascript AngularJS$emit在添加要注销的代码后不会触发事件,javascript,angularjs,javascript-events,Javascript,Angularjs,Javascript Events,我刚刚了解了如何使用$broadcast和$emit在控制器之间进行通信,在我的POC中进行了尝试,结果成功了,中描述的原始问题仍然没有解决,但现在我有另一个问题,该事件已被注册多次,因此我尝试以我在多篇帖子中看到的方式取消注册,但现在该事件不会触发。代码如下: tabsApp.controller('BasicOverviewController', function ($scope, $location, $rootScope) { var unbind = $rootScope.$

我刚刚了解了如何使用$broadcast和$emit在控制器之间进行通信,在我的POC中进行了尝试,结果成功了,中描述的原始问题仍然没有解决,但现在我有另一个问题,该事件已被注册多次,因此我尝试以我在多篇帖子中看到的方式取消注册,但现在该事件不会触发。代码如下:

tabsApp.controller('BasicOverviewController', function ($scope, $location, $rootScope) {
    var unbind = $rootScope.$on('displayModal', function (event, data) {
        if (data.displayModal) {
            alert("I want to display a modal!");
            var modal = $('#basicModal');
            modal.modal('toggle');
        }
    });

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

tabsApp.controller('SportsController', function SportsController($scope, $location, $rootScope) {
    $scope.goToOverview = function (showModal) {
        $location.path("overview/basic");
        $rootScope.$emit('displayModal', { displayModal: showModal })
    };
});
如果我移除

var unbind=


事件触发,我可以看到警报。只要我添加代码以注销事件,代码就永远不会被触发。这两件事怎么能一起工作呢?

你能把unbind拉到它自己的函数中,然后像这样在两者中使用它吗

tabsApp.controller('BasicOverviewController', function ($scope, $location, $rootScope) {
    var unbind = function (event, data) {
        if (data.displayModal) {
            alert("I want to display a modal!");
            var modal = $('#basicModal');
            modal.modal('toggle');
        }
    };

    $rootScope.$on('displayModal', unbind);
    $scope.$on('$destroy', unbind);
});

我可能错了,但我的猜测是,
BasicOverviewController
没有被持久化,并且在
sportcontroller
有机会使用它之前,它的作用域正在被破坏。没有一个有效的例子,我无法推断更多。如果要在
$rootScope
上维护此功能,则可能的模式为:

if(!$rootScope.displayModalDereg){
$rootScope.displayModalDereg=$rootScope.on('displaymodel',函数(事件,数据){
if(data.displaymodel){
警报(“我想显示模式!”);
var模态=$(“#基本模态”);
modal.modal('toggle');
}
});
这还允许您检查并查看是否有已注册的事件,以便在需要时对其进行解除记录

if($rootScope.displayModalDereg){//此事件已注册
$rootScope.displayModalDereg();
$rootScope.dispalyModalDereg=未定义;
}
我强烈建议创建一个displaymodel指令来保存所有这些,而不是在
$rootScope
上维护它。显然,您仍然会
$emit
,或者更好的是,从$
rootScope
创建
$broadcast
,只是不在那里保存dereg函数

下面是我曾经写过的一个模态指令的示例:

/**
*
*模态指令
*/
"严格使用",;
(函数initModalDrtv(窗口){
var angular=window.angular,
app=window.app;
角度.module(app.directions).directive('modalDrtv'[
“$rootScope”,
函数modalDrtv($rootScope){
返回{
限制:“A”,
作用域:{},
templateUrl:“/templates/modal.html”,
替换:正确,
编译:函数modalCompileFn(远程通讯,tAttrs){
返回函数modalLinkFn(范围、元素、属性){
scope.show=false;
scope.options={
“标题”:“,
“消息”:“,
“标记”:未定义,
“按钮”:{
showCancel:false,
第二:错,
第二个操作:“”,
主要行动:“好的”
},
“responseName”:”
};
scope.respond=功能(响应){
var r='';
如果(响应===1){
r=scope.options.buttons.primaryAction;
}否则如果(响应===2){
r=scope.options.buttons.secondary动作;
}否则{
r=响应;
}
$rootScope.$broadcast(scope.options.responseName,r);
scope.show=false;
};
作用域:$on('initIrpModal',函数(事件、数据){
如果(angular.isUndefined(data))抛出新错误(“irp模态事件中缺少数据”);
scope.options.title=data.title;
scope.options.message=data.message;
scope.options.buttons.showCancel=data.buttons.showCancel;
scope.options.buttons.showSecondary=data.buttons.showSecondary;
scope.options.buttons.secondary动作=data.buttons.secondary动作;
scope.options.buttons.primaryAction=data.buttons.primaryAction;
scope.options.responseName=data.responseName;
scope.show=true;
});
}
}
}
}
]);
})(窗口);

此指令使用一个模式,让应用程序中的任何地方都使用它。注册的事件位于其隔离作用域上,因此在模式作用域被销毁时将被销毁。它还配置了一个响应名称,以便如果需要用户响应,它可以广播一个事件,让应用程序中包含的部分初始化我听到了响应。

那么,在上面的脚本中,哪一个是您的取消注册事件?我找不到它。@IqbalFauzi我知道$scope.$on(“$destroy”…)是取消注册事件的内容。我可能丢失了一些内容,因此问题是,这是所有正在使用的代码。
$destroy
事件只有在范围被销毁时才会被调用,这意味着您的
displaymodel
将在范围被销毁时注册。@ZackArgyle下面的答案是注册和取消注册事件的正确方法,我知道。这似乎不起作用。事件未被注销,因此每次尝试时都会有一个额外的警报。