4

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

是否有解决此类问题的通用方法?

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

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

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

用户界面草图

4

3 回答 3

1

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

  1. 应用于 Javascript 的中介者模式
  2. 中介者模式 javascript
于 2012-06-02T10:26:54.283 回答
1

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

正如 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() 函数会显示您忽略了可能导致意外行为的某些事件组合的位置。

事件/状态的决策表

于 2012-06-02T11:44:53.760 回答
0

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

(start state) -> [event] -> <action> -> [event] -> <action> ...

因为在每个点都可能发生不同的事件,所以事件树随着观察到的分支的长度呈指数增长。幸运的是,界面通常会返回到某个过去的状态,例如在关闭对话框后它会返回到开始状态。

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

于 2012-06-18T11:42:19.493 回答