Javascript 如何在模块化用户界面中管理基于事件的输入?

Javascript 如何在模块化用户界面中管理基于事件的输入?,javascript,user-interface,event-handling,modular,Javascript,User Interface,Event Handling,Modular,用户界面通常由不同的输入设备组成,如按钮、输入字段、对话框、滑块等。事件顺序通常决定预期的行为,而这种行为通常不容易在简单的规则中捕捉到 对于这类问题是否有一种通用方法 以一个带有3个切换按钮的界面为例,说明界面变得复杂是多么容易。如果按钮单击的行为取决于每个按钮的状态,则可能出现2^3*3=24个事件情况。如果行为还依赖于事件历史记录,则事件案例的数量将呈指数增长 作为一个真实的例子,看看我正在开发的所见即所得文本编辑器。我在编辑器上选择聚焦/模糊事件以启用/禁用编辑器。一些按钮(小部件)会立

用户界面通常由不同的输入设备组成,如按钮、输入字段、对话框、滑块等。事件顺序通常决定预期的行为,而这种行为通常不容易在简单的规则中捕捉到

对于这类问题是否有一种通用方法

以一个带有3个切换按钮的界面为例,说明界面变得复杂是多么容易。如果按钮单击的行为取决于每个按钮的状态,则可能出现2^3*3=24个事件情况。如果行为还依赖于事件历史记录,则事件案例的数量将呈指数增长

作为一个真实的例子,看看我正在开发的所见即所得文本编辑器。我在编辑器上选择聚焦/模糊事件以启用/禁用编辑器。一些按钮(小部件)会立即将焦点返回编辑器,而其他按钮会打开对话框。在下图中,箭头显示了单击界面元素时焦点的位置

我发现焦点的管理在这里是一个棘手的问题,经常会引入不受欢迎或违反直觉的行为

您可以使用AKAMessage Broker模式来解耦UI组件(通常是任何类型的应用程序组件),这里有两篇关于它的文章:


  • 正确回答我的问题是答案的一部分。我的问题是关于一种特殊情况,在这种情况下,小部件不仅是数据的表示,而且是共享信息的输入设备

    Matteo Migliore建议的事件调度器具有不同的用途。在信息流更为线性的情况下,它很有用:一方面是一个或多个可以触发事件的对象,另一方面是侦听这些事件的对象

    在我的例子中,不仅事件的管理应该是集中的,更重要的是,逻辑的管理也应该是集中的。这种逻辑的特点是多个执行器以一种容易引起循环的方式影响同一数据源。在我的例子中,这个数据源是:焦点在哪里,何时激活/停用编辑器

    防止循环的解决方案是使用内部状态变量并仔细设计映射,将每个状态+事件组合转换为操作+新状态。一个基本的实现可以如下所示:

    switch (eventdescription) {
      case 'click_in_txt':
        switch (state) {
          case 'inactive':
            activate();
            state = 'active';
            break;
          case 'plugin_has_focus';
            close_plugin();
            state = 'active'
            break;
          default:
            console.log('undefined situation ' + state + ' / ' + eventdescription);
        }
      ...
    }
    
    这种方法仍然需要一些尝试和错误,但是很容易看出哪种情况会导致错误,然后您可以单独更改该情况下的行为。此外,console.log()函数还显示了您忽略了可能导致意外行为的某些事件组合的地方


    我能想象的最通用的方法是绘制事件树。此事件树的单个分支的通用表示形式如下所示:

    (start state) -> [event] -> <action> -> [event] -> <action> ...
    
    (开始状态)->[event]->->[event]->。。。
    
    因为在每个点上可能发生不同的事件,所以观察到的分支越长,事件树就呈指数增长。幸运的是,接口通常会返回到某个过去的状态,例如,关闭对话框后,它将返回到开始状态


    查找和建模这些返回状态是一个创造性的过程,对于每个应用程序都是独一无二的。命名这些状态中的每一个都很有帮助。中间结果是如上所示的状态/事件/动作图。

    @Sagiv现在对话框的打开和关闭都有事件处理程序,将焦点返回到#txt(默认行为)。该对话框还有一个公共函数,编辑器在(2)的情况下调用该函数。在这里,我设置了一个标志来阻止默认行为。这是可行的,但我不想让带有对话框的新插件实现同样的功能,同时我想让它们拥有自己的功能(例如,不同CMS解决方案的图像上传)查看BackboneJS,它非常适合在UI中控制和共享事件。@AlienWebguy。我最近学习了主干,它做得很好。但在我看来,这并不能解决我的前三颗子弹。(也许我们的评论是在我更新我的问题之前发布的,所以没有冒犯)当然会-你可以让每个视图监听其他视图的事件,但更重要的是,它们可以监听模型和集合中的更改。这就是主干如此强大的原因,一个视图可以更新模型上的属性值,整个UI都会知道并相应地更新自己。我不确定,因为在我的例子中,我有一个中心对象,编辑器,它可能已经管理了所有事件。我的问题仅仅是让所有事件在整个系统的不同状态下正常工作,而不是所有信息在任何时候都可用(例如,当模糊事件在文本上触发时,甚至不清楚导致它的按钮上的鼠标下降是否会变成点击。(鼠标下降->鼠标上升->点击)你的回答启发了我,让我带上我自己的答案,所以对你来说+1!太好了:),发送消息是从UI组件公开函数的最好方式,而不知道shell是如何组成的。我修改了我的问题,以解决剩下的问题,即如何管理中心对象内部的事件