如何使用.$emit
和.$on
方法将$scope
对象从一个控制器发送到另一个控制器?
function firstCtrl($scope) {
$scope.$emit('someEvent', [1,2,3]);
}
function secondCtrl($scope) {
$scope.$on('someEvent', function(mass) { console.log(mass); });
}
它不像我认为的那样工作。 $emit
和$on
work 如何运作?
首先,父子范围关系确实很重要。你有两种可能发出一些事件:
$broadcast
- 将事件向下发送到所有子范围, $emit
- 通过范围层次结构向上调度事件。 我对控制器(范围)关系一无所知,但有几种选择:
如果范围firstCtrl
是母公司secondCtrl
范围,你的代码应该通过更换工作$emit
由$broadcast
在firstCtrl
:
function firstCtrl($scope)
{
$scope.$broadcast('someEvent', [1,2,3]);
}
function secondCtrl($scope)
{
$scope.$on('someEvent', function(event, mass) { console.log(mass); });
}
如果您的范围之间没有父子关系,您可以将$rootScope
注入控制器并将事件广播到所有子范围(即secondCtrl
)。
function firstCtrl($rootScope)
{
$rootScope.$broadcast('someEvent', [1,2,3]);
}
最后,当您需要将子控制器中的事件调度到范围向上时,您可以使用$scope.$emit
。如果firstCtrl
范围是firstCtrl
范围的父secondCtrl
:
function firstCtrl($scope)
{
$scope.$on('someEvent', function(event, data) { console.log(data); });
}
function secondCtrl($scope)
{
$scope.$emit('someEvent', [1,2,3]);
}
我还建议第四个选项作为 @zbynour 提议选项的更好替代方案。
无论传输和接收控制器之间的关系如何,都使用$rootScope.$emit
而不是$rootScope.$broadcast
。这样,事件保持在$rootScope.$$listeners
的集合中,而使用$rootScope.$broadcast
,事件传播到所有子范围,其中大多数可能不是该事件的监听器。当然,在接收控制器的最后,你只需使用$rootScope.$on
。
对于此选项,您必须记住销毁控制器的 rootScope 侦听器:
var unbindEventHandler = $rootScope.$on('myEvent', myHandler);
$scope.$on('$destroy', function () {
unbindEventHandler();
});
如何使用。$ emit 和。$ on 方法将 $ scope 对象从一个控制器发送到另一个控制器?
您可以在应用层次结构中发送所需的任何对象,包括$ scope 。
这是关于广播和发射如何工作的快速概念。
注意下面的节点; 全部嵌套在节点 3 中。当您拥有此场景时,您将使用广播并发出 。
注意:此示例中每个节点的数量是任意的; 它很容易成为头号人物; 二号; 甚至是 1,348 号。每个数字只是此示例的标识符。这个例子的重点是显示 Angular 控制器 / 指令的嵌套。
3
------------
| |
----- ------
1 | 2 |
--- --- --- ---
| | | | | | | |
看看这棵树。你如何回答以下问题?
注:还有其他的方法来回答这些问题,但在这里我们将讨论广播和散发 。此外,当阅读下面的文本时,假设每个数字都有自己的文件(指令,控制器)ex one.js,two.js,three.js。
如何节点1发言,节点3?
在文件one.js 中
scope.$emit('messageOne', someValue(s));
在文件three.js 中 - 所有子节点的最高节点需要进行通信。
scope.$on('messageOne', someValue(s));
节点 2 如何与节点 3 对话?
在文件two.js 中
scope.$emit('messageTwo', someValue(s));
在文件three.js 中 - 所有子节点的最高节点需要进行通信。
scope.$on('messageTwo', someValue(s));
节点 3 如何与节点 1 和 / 或节点 2 通话?
在文件three.js 中 - 所有子节点的最高节点需要进行通信。
scope.$broadcast('messageThree', someValue(s));
在文件one.js && two.js 中您要捕获消息的文件或两者。
scope.$on('messageThree', someValue(s));
节点 2 如何与节点 1 通信?
在文件two.js 中
scope.$emit('messageTwo', someValue(s));
在文件three.js 中 - 所有子节点的最高节点需要进行通信。
scope.$on('messageTwo', function( event, data ){
scope.$broadcast( 'messageTwo', data );
});
在文件one.js 中
scope.$on('messageTwo', someValue(s));
然而
当你让所有这些嵌套的子节点试图像这样进行通信时,你会很快看到许多$ on , $ broadcast和$ emit 。
这就是我喜欢做的事情。
在最高的 PARENT NODE(在这种情况下为3 ......),这可能是你的父控制器......
所以,在文件three.js 中
scope.$on('pushChangesToAllNodes', function( event, message ){
scope.$broadcast( message.name, message.data );
});
现在,在任何子节点中,您只需要$ $ 发出消息或使用$ on捕获它。
注意:通常很容易在一个嵌套路径中进行串扰,而不使用$ emit , $ broadcast或$ on ,这意味着大多数用例都是在您尝试让节点1与节点2进行通信时,反之亦然。
节点 2 如何与节点 1 通信?
在文件two.js 中
scope.$emit('pushChangesToAllNodes', sendNewChanges());
function sendNewChanges(){ // for some event.
return { name: 'talkToOne', data: [1,2,3] };
}
在文件three.js 中 - 所有子节点的最高节点需要进行通信。
我们已经处理过这个了吗?
在文件one.js 中
scope.$on('talkToOne', function( event, arrayOfNumbers ){
arrayOfNumbers.forEach(function(number){
console.log(number);
});
});
您仍然需要对要捕获的每个特定值使用$ on ,但现在您可以在任何节点中创建任何您喜欢的内容,而不必担心如何在我们捕获和广播时跨父节点间隙获取消息通用pushChangesToAllNodes 。
希望这可以帮助...