Javascript $rootScope作为事件聚合器
我使用的是AngularJS。我有一个服务,需要在每次发生事件时触发事件。为此,我需要一个充当Javascript $rootScope作为事件聚合器,javascript,angularjs,angularjs-scope,Javascript,Angularjs,Angularjs Scope,我使用的是AngularJS。我有一个服务,需要在每次发生事件时触发事件。为此,我需要一个充当事件聚合器的对象 我需要建一个吗?或者我应该使用$rootScope 如果我应该使用$rootScope,如何确保没有事件名称冲突 对于不需要传播到子范围的事件,使用$rootScope是否有效 看看http://docs.angularjs.org/api/ng.$rootScope.Scope#$broadcast 使用$rootScope作为事件聚合器是完全可以的,除非您触发的事件超出了滑动摘要周
事件聚合器的对象
我需要建一个吗?或者我应该使用$rootScope
李>
如果我应该使用$rootScope
,如何确保没有事件名称冲突李>
对于不需要传播到子范围的事件,使用$rootScope
是否有效李>
看看http://docs.angularjs.org/api/ng.$rootScope.Scope#$broadcast
使用$rootScope
作为事件聚合器是完全可以的,除非您触发的事件超出了滑动摘要周期
或同时触发多个(100+)事件,而某些其他解决方案可能更合适
一种公认的做法是使用名称空间(namespace:event
-由Backbone.marionete
使用的模式)
在子作用域上使用$emit
,而不是在$rootScope
-$emit
上使用$broadcast
只向上传播,其中$broadcast
向下传播-到所有子作用域
我在平板电脑的web项目中建模并实现了以下机制:
在服务中定义通知。我不想使用术语events,因为我不希望团队中的其他开发人员将它与DOM事件混淆。对于支持intellisense的IDE和调试来说,通知的半类型名称更容易。例如,我有一个设备
服务,当平板电脑设备的方向改变时,它将$broadcast(Device.Notification.orientationIDChange)
根据需要,使用Scope
对象来$broadcast
或$emit
通知。比如说,
- 对于像上一个一样的全局通知,我会:
$rootScope.$broadcast(Device.Notification.OrientationDidChange)
。因此,所有侦听器都可以在自己的作用域上侦听,而无需注入$rootScope
- 对于可能只影响当前作用域(及其子作用域)的本地通知,例如作用域需要通知其所有子作用域当前控制器的布局已更改的通知,通常我会这样做:
scope.$broadcast(UI.notification.NeedsLayout)
,其中,UI
是用于保存UI相关常量的预定义服务,scope
是当前作用域
- 对于子作用域需要向上发送的某些通知,例如,一个slider指令告诉上升作用域
rangeStart
值已更改(除了常规的双向绑定),我使用:scope.$emit(slider.Notification.RangeStartDiChange)
,其中,范围
是当前范围
这种方法在小项目中有点冗长。您可能希望始终坚持使用$rootScope.$emit(通知)
,并让所有侦听器执行$rootScope.$on(通知,回调)
来接收这些通知
在某些情况下,您可能希望在集中式服务中定义这些通知,以便更轻松地避免名称冲突。它实际上基于项目的命名约定
这些通知的实现(实际值)可能会有所不同。我更喜欢使用字符串
使用$broadcast
或$emit
还可以向侦听器传递其他参数,例如,$broadcast(通知,arg1,arg2)
。。。内容相当详细
你所说的事件聚合器是什么意思?它是广播活动的中心点吗?是否希望所有侦听器直接连接到事件聚合器?是。事件聚合器是一个中心对象,用于广播事件和其他对象侦听事件。例如,一个服务需要广播一个“action”事件,它将调用vent.trigger(“action”);以及其他执行vent.on('action',callback)的对象;将执行他们的回调。回答得好。注意:在$rootScope上,$broadcast和$emit将执行基本相同的操作。由于它是“根”。@blesh我认为这不正确,在$rootScope
上,$emit
将在那里触发(因为没有任何级别提升),而$broadcast
将传播到应用程序中的每个范围(这是性能杀手)。3。措词不当。我的意思是“在$rootScope上使用$emit而不是$broadcast”。我说得不够具体。