如何使用 .$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
如何工作?
13 回答
根据angularjs事件文档,接收端应该包含具有类似结构的参数
@params
事件是包含事件信息的事件对象
被调用者传递的 args(注意,这只能是一个总是更好地发送到字典对象中)
$scope.$on('fooEvent', function (event, args) { console.log(args) });
来自您的代码此外,如果您尝试在不同的控制器上获得共享的信息,还有另一种方法可以实现这一点,即角度服务 . 由于服务是单例,因此可以跨控制器存储和获取信息 . 简单地创建getter和该服务中的setter函数,公开这些函数,在服务中创建全局变量并使用它们来存储信息
您可以在应用层次结构中发送所需的任何对象,包括 $scope .
以下是关于 broadcast 和 emit 如何工作的快速概念 .
注意下面的节点;全部嵌套在节点3中 . 如果有此方案,则使用 broadcast 和 emit .
Note: 此示例中每个节点的数量是任意的;它很容易成为头号人物;二号;甚至是1,348号 . 每个数字只是此示例的标识符 . 这个例子的重点是显示Angular控制器/指令的嵌套 .
看看这棵树 . 你如何回答以下问题?
Note: 还有其他方法可以回答这些问题,但在这里我们将讨论 broadcast 和 emit . 此外,当阅读下面的文本时,假设每个数字都有自己的文件(指令,控制器)e.x. one.js,two.js,three.js .
节点 1 如何与节点 3 说话?
在文件 one.js
在文件 three.js 中 - 通信所需的所有子节点的最高节点 .
节点2如何与节点3通信?
在档案 two.js
在文件 three.js 中 - 通信所需的所有子节点的最高节点 .
节点3如何与节点1和/或节点2通话?
在文件 three.js 中 - 通信所需的所有子节点的最高节点 .
在文件 one.js && two.js 中您要捕获消息的文件或两者 .
节点2如何与节点1通信?
在文件 two.js
在文件 three.js 中 - 通信所需的所有子节点的最高节点 .
在文件 one.js
HOWEVER
这是我喜欢做的事情 .
在最上面的PARENT NODE(在这种情况下是 3 ......),这可能是你的父控制器......
所以,在文件 three.js
现在,在任何子节点中,您只需要 $emit 消息或使用 $on 捕获它 .
NOTE: 在不使用 $emit , $broadcast 或 $on 的情况下,通常很容易在一个嵌套路径中进行串扰,这意味着当您尝试使节点 1 与节点 2 进行通信时,大多数用例都适用,反之亦然 .
节点2如何与节点1通信?
在文件 two.js
在文件 three.js 中 - 通信所需的所有子节点的最高节点 .
我们已经处理过这个了吗?
在档案 one.js
您仍然需要将 $on 与您想要捕获的每个特定值一起使用,但现在您可以在任何节点中创建任何您喜欢的内容,而不必担心如何在父节点间隙中获取消息,因为我们捕获并广播通用 pushChangesToAllNodes .
希望这可以帮助...
要将
$scope object
从一个控制器发送到另一个控制器,我将在这里讨论$rootScope.$broadcast
和$rootScope.$emit
,因为它们最常用 .Case 1 :
$ rootScope $广播: -
$rootScope
监听器不会自动销毁 . 你需要使用$destroy
销毁它 . 最好使用$scope.$on
,因为$scope
上的监听器会被自动销毁,即只要$ scope被销毁 .要么,
Case 2:
. $ rootScope $发出:
The major difference in $emit and $broadcast is that $rootScope.$emit event must be listened using $rootScope.$on, because the emitted event never comes down through the scope tree. .
在这种情况下,你也必须像$ broadcast那样销毁监听器 .
Edit:
Edit 2 :
这是我的功能:
您必须使用$ rootScope在同一个应用程序中的控制器之间发送和捕获事件 . 将$ rootScope依赖项注入控制器 . 这是一个有效的例子 .
链接到$ scope对象的事件只在所有者控制器中工作 . 控制器之间的通信通过$ rootScope或Services完成 .
我最终添加了一个外部EventEmitter库来作为服务进行投影,并将其注入到我需要的任何地方 . 因此,我可以在任何地方“发射”和“开启”任何地方,而无需关心范围继承 . 这种方式不那么麻烦,肯定会有更好的性能 . 对我来说也更具可读性 .
通配符支持:EventEmitter2
表现良好:eventemitter3
其他选择:Drip
范围可用于传播,将事件分派给范围子项或父项 .
$emit - 将事件传播到父级 . $broadcast - 将事件传播给子项 . $on - 侦听事件的方法,由$ emit和$ broadcast传播 .
示例index.html:
示例app.js:
在这里你可以测试代码:http://jsfiddle.net/zp6v0rut/41/
首先,父子范围关系确实很重要 . 你有两种可能发出一些事件:
$broadcast
- 将事件向下调度到所有子范围,$emit
- 通过范围层次结构向上调度事件 .我对控制器(范围)关系一无所知,但有几种选择:
firstCtrl
的范围是secondCtrl
范围的父级,则您的代码应该通过在firstCtrl
中将$emit
替换为$broadcast
来工作:$rootScope
注入控制器并将事件广播到所有子范围(即secondCtrl
) .$scope.$emit
. 如果firstCtrl
的范围是secondCtrl
范围的父级:我还建议第四个选项作为@zbynour提议选项的更好替代方案 .
无论传输和接收控制器之间的关系如何,都使用
$rootScope.$emit
而不是$rootScope.$broadcast
. 这样,事件仍然在$rootScope.$$listeners
的集合内,而对于$rootScope.$broadcast
,事件传播到所有子范围,其中大多数可能不是该事件的监听者 . 当然,在接收控制器的最后,你只需使用$rootScope.$on
.对于此选项,您必须记住销毁控制器的rootScope侦听器:
最简单的方法:
您可以从控制器调用返回承诺的服务,然后在控制器中使用它 . 并进一步使用
$emit
或$broadcast
通知其他控制器 . 在我的情况下,我不得不通过我的服务进行http调用,所以我做了类似这样的事情:我的服务看起来像这样
下面的代码显示了从事件向上调度到父控制器的两个子控制器(rootScope)
http://jsfiddle.net/shushanthp/zp6v0rut/