我一直在各种环境中使用 Dojo,但从未找到关于事件与主题的良好解释。我对使用这两种机制的理解如下:
- 两者都是事件或更普遍的消息机制。
- 两者的工作原理大致相同,都是通过设置回调来订阅主题/事件。
- 事件与对象/小部件紧密耦合,例如,您需要对象或小部件的实际实例来注册特定事件的监听器。
- 另一方面,主题机制提供了一种更加解耦的方法,因为您可以订阅任何主题,而无需知道哪个组件正在发布该主题,甚至根本不知道该主题是否会发布。
我在使用 Dojo 开发自定义小部件时使用过几次的方法是让它们发布到某些主题。其他组件将订阅这些主题并做出适当的 react 。然而,这会导致代码难以理解,因为当您找到订阅某个主题的一段代码时,您开始想知道谁在发布该主题,反之亦然。目前,我倾向于让我的自定义小部件提交事件,并让 Controller 监听这些事件,并将它们分派(dispatch)到应对这些事件使用react的其他小部件。
因此,在第一种方法中,主题机制是小部件之间的粘合剂,但它是分散的,这使得根据我的经验很难长期维护代码。在第二种方法中, Controller 类(遵循 MVC 模式)是粘合剂,它集中事件处理。
我有兴趣知道这是否是对这两种机制的正确理解。我也对选择两者之一(或什至混合它们?)时应考虑的任何设计考虑感兴趣。任何有关该主题的详细讨论的指示也将不胜感激。我一直在看:http://dojotoolkit.org/documentation/tutorials/1.9/events/但这主要描述了两种机制的工作原理,但对如何构建复杂的应用程序几乎没有提供任何见解。
最佳答案
我对主题和事件的想法与您完全相同。由于 JavaScript 是事件驱动的,因此两者当然都是事件驱动的(就像您在第一点中所描述的那样)。
事件确实与小部件本身耦合,而主题则不然。我通常将其视为以下内容:
- 当您具有主从结构(例如包含许多项目的列表)时,使用小部件和事件可能是解决问题的最佳方法。
- 当两个小部件彼此无关时,主题可能是彼此之间沟通的最佳方式。
你说得对,主题让人更难知道起源是什么,但如果你想一想,你就不需要知道起源。这些主题为您提供了一个 API,可将源与目标解耦,使您无需了解源。
因为这两个小部件是不相关的(这是我遵循的方法,之前描述过),所以在维护代码时通常不需要知道来源是什么。
您需要的是一个编写良好的 API,并确保作为目标的源都遵循它。如果 API 发生更改(代码维护),您可以使用 IDE 找出正在发布/订阅的小部件(例如通过搜索主题名称)并确保每个小部件都已更新。
您还可以选择封装发布/订阅行为并通过创建如下模块来提供更高级别的 API:
define([ "dojo/topic", "dojo/_base/array" ], function(topic, arrayUtils) {
var MY_TOPIC = "/my/topic";
var module = {
observers: [],
notify: function(/** String */ name, /** Integer */ age) {
topic.publish(MY_TOPIC, {
name: name,
age: age
});
},
addObserver: function(/** Function */ callback) {
return this.observers.push(callback) - 1;
},
removeObserver: function(/** Integer */ index) {
this.observers[index] = null;
}
};
topic.subscribe(MYTOPIC, function(data) {
arrayUtils.forEach(module.observers, function(observer) {
if(observer !== null && data.name !== undefined && data.age !== undefined) {
observer(name, age);
}
});
});
return module;
});
您使用 notify()
函数(提供正确的函数参数)进行发布,并使用其他函数添加/删除观察者。然后,您将使该组件成为您的唯一订阅者,并使其通知所有观察者。
这样你就不需要了解主题,而且 API 是统一的。您只需确保回调正确使用参数即可。要维护您的代码,您只需更改高级 API 并查找使用此高级组件的模块。由于它位于 require()
函数中,因此更容易检测到。
当我使用主题时,我通常会创建一个像这样的高级 API(可能会根据它的使用情况而有所改变)。但我认为所表达的观点很明确,更改主题和修改发送的数据更容易。
关于events - Dojo:主题与事件,应该考虑哪些设计注意事项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21453627/