6

我正在为我的工作创建一种基于中介的库。我们创建了很多应用程序,所以我想要一些可以在每个应用程序的基础上轻松获取和修改的东西。我还希望它能够很容易地创建“小部件”(因为没有更好的术语)并且很容易删除它们而不必担心破坏任何东西。我们制作的许多这些应用程序也可以由为应用程序制作应用程序或小部件的外部开发人员扩展。

这就是我遇到中介者模式的方式。我写了一些类似这样的东西:

//Extend
Core.extend('widget',function(params){
  alert(params.message);
});

//Load it
Core.load('widget',{message:'Hello World'});

//Remove it
Core.remove('widget');

我有3个问题:

  1. 在这种模式下,你如何/应该使用 JavaScript 处理 DOM 操作?我不希望开发人员在他们的小部件之外弄乱 DOM。

  2. 您如何/应该如何处理 AJAX 请求。你应该做点什么吗?您是否应该只在库中提供 AJAX/JSONP 调用(Core在本例中)。

  3. 我最大的问题是,您实际上如何与其他小部件进行交互?我不想紧耦合(显然),但我不明白你将如何与另一个小部件交互。例如,假设您有一个文本框,并在提交时将其发送到数据库。另一个小部件,让我们称之为“时间线”小部件,现在当它被提交时,然后使用文本框小部件中的文本更新时间线?

===更新===

我最终写了这个:

http://oscargodson.github.com/Core.js/

4

1 回答 1

3

与小部件交互的小部件:几天前我刚刚完成了这个构建。我查看了你实现它的方式,这里有一些额外的想法给你。

您构建的推送系统与 jQuery 的 DOM 事件系统非常相似,可以发送和接收任意事件。我一直在使用该系统开发解耦小部件,但我发现它非常需要,因为最终“推送”(事件、发射等)脱离了上下文——因为听众不知道这是否在他们审问事件之前,甚至在他们想要的范围内。

例如,假设网页上的每个 UI 元素都是系统中的小部件。一页上很容易有30多个。如果每个人都推送“加载”消息,那么其他 29 个必须接收它。此外,正如您所提到的,第 3 方开发人员将为此系统进行开发。然后,它让他们承担过滤他们不想接收的消息的负担。

我在最新的小部件通信系统中采用的方法是我所说的“pubstring”/“substring”方法(公平地说,我相信其他人在我之前提出了这个想法并且听起来很酷为其命名)。基本上,每当一个小部件“推送”时,该推送都会变成一个字符串,其中包含:领域(上下文)、小部件的类型、小部件的特定 ID(无论它可能是什么)以及特定消息。

例如,一个 ID 为 45 的小部件,输入“tweet-list”,在“自定义”领域中推送一条“已加载”消息。然后,pub 字符串将呈现为: custom.tweet-list.45.loaded

放置订阅时,它们是通过一个哈希表输入的,该哈希表可以选择包含 4 个属性的值(除了我拥有的领域/类型/id/msg 之外,您还可以轻松添加更多)。聆听将是这样的:

listen({ realm: 'custom', type: 'whatever' }, f); // (where 'f' is a function)

框架的侦听器部分可以将该哈希表转换为“子字符串”,这将是一个正则表达式,表示它所代表的过滤器:

custom\.whatever\.[^\.]+\.[^\.]+

该正则表达式存储为某个隐藏数组的编译正则表达式......

__subscriptions.push(new RegExp(subString));

然后,每当推送(即发布)某些内容时,框架基本上会遍历 __subscriptions 数组,触发.test每个存储的子字符串(正则表达式),并在匹配时执行该子字符串的回调。

使用这个系统,可以应用无限制的过滤侦听器,并且侦听器知道他们正在接收仅针对他们感兴趣的上下文的通知。

例子:

// Listen for all messages by widget ID #99
listen({ id: 99 } ,f);

// Listen for all messages by widgets in realm clientB
listen({ realm: 'clientB' }, f);

// Listen for the data-received push of widgets whose type is tweet-list
listen({ type: 'tweet-list', message: 'data-received' }, f);

因为正则表达式实际上只是一个串联,所以正则表达式也可以包含在过滤器中。

// Listen for any data- message
listen({ message: 'data-[^\.]+' }, f);

这个系统的美妙之处在于,您仍然可以保持当前界面“保持简单”,只需测试argument[0]. 换句话说..

// This
listen('loaded', f);

// Could be equivalent to this on the backend:
listen({ message: 'loaded' }, f);

我知道那很长,但希望它能给你一些想法。

于 2011-09-19T23:06:41.763 回答