无论框架如何,在 UI 渲染后发布/订阅事件都是最佳实践吗?
我继承了相当大的 Javascript/ExtJS3 代码库,并且在调用“...superclass.initComponent.apply(this,arguments)”之后,在重写的 initComponent 方法内部有许多调用事件的实例。特定事件以如下方式在特定对象上调用:
this.filter.on('filterUpdated', function(filter, params)
我已经开始将代码转换为使用发布/订阅范例,以减少对象与其特定事件名称之间的耦合,但很快就遇到了问题发布和/或订阅 initComponent 中的事件(在 ExtJS 中在渲染之前执行)。当屏幕首次加载时,我需要从最高级别的组件触发“INIT”事件,并且我要么收到错误(由于 ExtJS“模板”没有被渲染),要么根本没有触发事件。
然后我在 Ext.Component 的 ExtJS 源代码中阅读了以下内容(所有组件均从中扩展),我顿时顿悟:
if (this.tpl) {
if (!this.tpl.compile) {
this.tpl = new Ext.XTemplate(this.tpl);
}
if (this.data) {
this.tpl[this.tplWriteMode](contentTarget, this.data);
delete this.data;
}
}
this.afterRender(this.container);
当我切换到从最顶层组件的 afterRender 方法发布“INIT”事件并订阅时来自所有其他组件的 afterRender 方法的所有事件,一切都按我的预期进行。现在我只是想知道,主要是为了验证我的设计......
这是在事件驱动的 UI 中实现发布/订阅的普遍接受的方式吗?甚至不考虑框架?即以下2个好的原则,还是其他的方式?
- “初始化事件”应在所有子组件渲染后发布
- 所有子组件应在渲染后订阅所有事件(为了安全起见)
提前致谢
I've inherited a rather large Javascript/ExtJS3 code base, and there are many instances of invoking events inside of the overridden initComponent method, after the call to "...superclass.initComponent.apply(this, arguments)". Specific events are being invoked on specific objects in a manner such as the following:
this.filter.on('filterUpdated', function(filter, params)
I've started converting the code to use a pub/sub paradigm instead, to reduce the coupling between objects and their specific event names, but quickly ran into issues when publishing and/or subscribing to events within initComponent (which in ExtJS executes before rendering). I need to fire an "INIT" event from the highest level component when the screen first loads, and I was either getting an error (due to ExtJS "templates" not having been rendered as it turns out), or events not firing at all.
Then I read the following in the ExtJS source for Ext.Component (from which all components extend) and I had an "aha" moment:
if (this.tpl) {
if (!this.tpl.compile) {
this.tpl = new Ext.XTemplate(this.tpl);
}
if (this.data) {
this.tpl[this.tplWriteMode](contentTarget, this.data);
delete this.data;
}
}
this.afterRender(this.container);
When I switched to both publishing the "INIT" event from my topmost component's afterRender method, and subscribing to all events from all other components from their afterRender methods, everything worked as I expected. And now I am just wondering, largely to validate my design....
Is this a generally accepted way of implementing pub/sub in an event driven UI? Regardless of framework even? Namely are the following 2 good principles, or are their other ways?
- "Initialization events" should get published after all sub-components have rendered
- All sub-components should subscribe to all events (to be on the safe side) after they have rendered
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您必须平衡事件处理的开销与丢失重要事件的可能性。在 js/DOM 中,土地状态是可变的。
对于#1,如果您可以确定所有子组件都已渲染并订阅的时间点,则触发 init 事件是有意义的。
对于#2,每个人监听事件似乎都是安全的;然而,这可能会减慢速度。如果性能问题很明显,您可能必须决定不关心哪些事件并避免订阅。
You have to balance the overhead of event handling vs. the possibility of missing significant events. In js/DOM land state is mutable.
For your #1 if you can identify a point in time when all your sub-components have rendered and subscribed, firing an init event makes sense.
For #2, it seems safe everyone to listen for events; however it could slow things down. If performance issues are apparent you may have to decide what events you don't care about and avoid subscribing.