JavaScript问题中的中介模式

Osc*_*son 6 javascript oop design-patterns mediator

我正在为我的工作创建一种基于调解器的库.我们创建了大量应用程序,因此我想要一些可以在每个应用程序的基础上轻松获取和修改的内容.我也希望它很容易创建"小部件"(缺少一个更好的术语)并且易于删除它们而不用担心破坏任何东西.我们制作的许多这些应用程序也可以由外部开发人员为应用程序制作应用程序或小部件进行扩展.

这就是我遇到调解员模式的方式.我写了一些像这样的东西:

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

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

//Remove it
Core.remove('widget');
Run Code Online (Sandbox Code Playgroud)

我有3个问题:

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

  2. 你应该如何/应该处理AJAX请求.你应该做什么吗?你应该只在库中提供一个AJAX/JSONP调用(Core在这个例子中).

  3. 我最大的问题是,你如何与其他小部件进行实际交互?我不想紧张夫妇(显然),但我不知道你如何与另一个小部件互动.例如,假设您有一个文本框,并在提交时将其发送到数据库.另外一个小部件怎么可以称之为"时间轴"小部件,现在它被提交,然后用文本框小部件中的文本更新时间轴?

=== UPDATE ===

我最后写了这个:

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

T. *_*one 3

小部件与小部件交互:我几天前刚刚完成构建。我仔细研究了您实现它的方式,这里有一些额外的想法供您参考。

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

例如,考虑一下网页上的每个 UI 元素是否都是系统中的一个小部件。一页上很容易就有 30 多个。如果每个人都推送一条“已加载”消息,则其他 29 个人必须接收该消息。此外,正如您提到的,第三方开发人员将为该系统进行开发。然后,它会给他们带来过滤掉他们不想接收的消息的负担。

我在最新的小部件通信系统中采用的方法就是我所说的“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);
Run Code Online (Sandbox Code Playgroud)

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

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

这个系统的美妙之处在于,您仍然可以保持当前的界面“让事情变得简单”,并且只测试字符串或哈希表argument[0]。换句话说..

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

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

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