这是Is publishing/subscribing to events after UI rendering a best practice regardless of framework?的后续问题,我上个月在第一次使用Javascript / ExtJS应用程序进入pub / sub路径时询问了这个问题。 如果你想从纯粹的发布 - 订阅角度来看待我的问题,请参阅下一个段落的第一个强调的句子。首先是一些背景:
我们有一个面板,其中包含一个标签面板,其面板中有一个网格面板,另一个面板包含一个用于过滤网格数据的表单。在beforechangetab事件中,我们添加/删除共享网格并发布GRID_TAB_TOGGLED消息以及指示库存或非库存的标志,然后网格重新加载适当的数据。
对于过滤器,我继承的代码仅依赖于一个表单,并且组合框选项会根据加载的库存/非库存数据进行修改,但现在我们需要保留所有过滤状态。我最初的想法是使用卡片布局来保存库存或非库存过滤器,并在响应相同的GRID_TAB_TOGGLED消息之间切换。
但问题是这两种过滤形式都需要监听其他大量相同的事件。我想我已经确定了一个解决方案,并且正在寻求设计验证。
我的想法是让不同的表单能够确定它们是“活动”(库存还是非库存)过滤器,如果是活动的,则订阅所有必要的消息,但如果不活动,则取消订阅来自所有人。只要收到GRID_TAB_TOGGLE消息,就会发生这种取消订阅的重新订阅。
从ExtJS的角度来看,这似乎是一个合理的设计,但对我来说更感兴趣(因为我有近3年的ExtJS经验,但只有1.5个月实现我自己的基于pub / sub的系统),来自发布/订阅范式立场?也许这甚至是基于pub / sub系统的模式(或者,尽管我希望不是,反模式)?
答案 0 :(得分:2)
我会避免过多的订阅/取消订阅。如果您要完全删除某个组件,那么很明显您应该从所有事件中取消订阅它。但是,当您暂时禁用该组件时,您还应该暂时禁用该事件。
因此,我不会取消订阅所有事件,然后再次重新订阅它们,而是会使用某种调解器将所有事件转发给我,并允许轻松暂停所有事件。这应该很容易使用Ext.util.Observable的#suspendEvents和#resumeEvents来实现。
Ext.define("EventMediator", {
extend: "Ext.util.Observable",
constructor: function(cmp, events) {
this.relayEvents(cmp, events);
this.callParent([]);
}
});
var med = new EventMediator(grid, ["click", "dblclick"]);
med.on("click", form.doSomething);
med.on("dblclick", form.doSomethingElse);
// When form gets hidden:
med.suspendEvents();