GWT 事件处理最佳实践
我有一个关于 GWT 客户端事件处理的问题。
在我们的应用程序中,我们有一个相当复杂的结构,由不同的模块和页面组成,它们通过客户端的 gwt eventbus 进行通信。我认为现在事件的数量增长得太快了。例如,我正在打开一个弹出窗口,我需要:
- 用于打开弹出窗口的事件
- 用于询问客户端内某些数据的事件
- 用于获取数据并填写对话框的
- 事件 用于关闭弹出窗口的
- 事件 用于处理保存按钮
Am 的 事件我认为 EventBus 实现有点复杂或遗漏了一些东西?我只是想从社区获得一些反馈,因为您也面临着同样的问题。
I have a question regarding the event handling on client side in GWT.
In our application we have a quite complex structure of different modules and pages which are communicating via the gwt eventbus on client side. Now the amount of events is growing to fast for my opinion. E.g. I am opening a popup I need:
- An event for opening the popup
- An event for asking some data within the client
- An event for getting back the data and fill in the dialog
- An event for closing the popup
- An event for handling the save Button
Am I thinking a little bit to complicated or missing something in the EventBus implementation? I just wanted to have some feedback out of the community as you are facing the same issues.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
就其价值而言,我有很多活动,也有更多的成长。是的,我想知道我是否可以少做一些事情,但是当我跳过一个事件并直接链接元素时,我会后悔。
这是我昨天刚刚修复的一个例子。我有一个 DataGrid 小部件。我还支持对列重新排序、隐藏列、重新调整列大小以及使用弹出对话框对列进行着色。您单击配置按钮,会显示一个列出列的弹出窗口,用户可以单击复选框来显示或隐藏列,单击上移/下移按钮来重新排序列,等等。在弹出窗口上点击“应用”,弹出窗口就会消失,并且 DataGrid 会重新配置。
但事实并非如此。您单击“应用”,弹出窗口就会放在那里,用户会想知道发生了什么,DataGrid 将在下面重新配置,然后弹出窗口就会消失。我们只聊了很短的时间——也许一秒钟或更长时间——但它是如此引人注目。为什么会发生这样的事?因为我很懒,将弹出窗口直接绑定到配置按钮,并将“应用”按钮直接绑定到 DataGrid。例如,您可以点击“应用”,然后将使用新的配置信息调用 DataGrid。只有当呼叫返回时,弹出窗口才会被拆除。
我知道这样做不好,但我很懒。因此,我花了 20 分钟在我的调解器单例中编写两条消息和关联的处理程序。一条消息由 DataGrid 发出以启动配置对话框,另一条消息由弹出窗口发出以配置 DataGrid。现在,小部件已解耦,性能更加快捷。没有“粘”感。
现在以你的例子来说,你能不能结合(1)和(2)?还有(3)、(4)和(5)?当用户单击我的应用程序上的配置按钮时,该事件会携带当前配置信息(包括对发起请求的 DataGrid 的引用)。您可以将此信息称为“有效负载”。当用户单击弹出窗口上的“应用”按钮时,事件负载包括事件处理程序在处理事件时将其提供给目标 DataGrid 的所有新配置信息(包括对原始目标 DataGrid 的引用)。两个事件——一个启动配置,一个应用最终结果。
是的,任何应用程序中都会有大量的事件来做一些有趣的事情,但事件可以携带大量信息,所以我会看看你的事件组织是否过于分散。
作为额外的一点,这是我使用的代码。我无耻地从谷歌的一个例子中复制了这种模式的元素。
用户可以使用菜单项寻求帮助:
对于事件(在本例中,当用户单击“帮助”菜单项时触发事件):
我有一个名为 Mediator 的单例,其中注册了所有事件:
每个事件都配对使用 Command 对象来完成工作:
一切都是解耦的。菜单小部件绑定到执行然后完成的命令。该命令在总线上触发事件然后完成。该事件触发命令的执行并完成。该命令显示弹出帮助面板(在本例中,向用户显示“未实现”消息——是的,我很快就会看到它)。与用户输入的每次交互都会非常快速地处理和解决。它可以启动一系列事件来执行较长的操作,但不会占用 GUI 来执行此操作。当然,由于元素是解耦的,我可以在其他地方调用相同的元素(例如,通过按钮按下以及菜单项调用帮助命令)。
For what it's worth, I have lots of events and more growing. And yes, I wonder if I can do with less, but when I skip an event and link elements directly, I regret it.
Here's an example that I just fixed up yesterday. I have a DataGrid widget. I also support re-ordering of columns, hiding of columns, re-sizing columns, and coloring columns with a popup dialog. You click on a configure button, and a popup with the columns listed shows, and the user can click checkboxes to show or hide columns, click on a Move Up / Move Down button to re-order columns, and so on. Hit Apply on the popup and the popup disappears and the DataGrid re-configures.
Except that it didn't. You'd click on Apply and the popup would just sit there, the user would wonder what was going on, the DataGrid would re-configure underneath, and then the popup would go away. We're only talking a short amount of time -- maybe a second or a bit more -- but it was so so noticeable. Why was it happening? Because I got lazy and tied the popup directly to the configure button, and the Apply button directly to the DataGrid. You'd hit Apply, for example, and the call would be made to the DataGrid with the new configuration information. Only when the call returned would the popup would be torn down.
I knew it was bad when I did it, but I was being lazy. So I took the 20 minutes I needed to write up two messages and associated handlers in my mediator singleton. One message is issued by the DataGrid to start the configuration dialog, and one is issued by the popup to configure the DataGrid. Now the widgets are de-coupled, and the performance is much snappier. There is no sense of "stickiness".
Now to your example, can you not combine (1) and (2)? And also (3), (4), and (5)? When the user clicks the configure button on my app, the event carries with it the current configuration information (including a reference to the DataGrid that originated the request). You can call this information the "payload". When the user clicks the Apply button on the popup, the event payload includes all the new configuration information (including a reference to that original target DataGrid) that the event handler feeds to the target DataGrid when the event is handled. Two events -- one to kick off the configuration and one to apply the end result.
Yes there are a plethora of events in any app that does something interesting, but events can carry a lot of information, so I would look at whether your event organization is too fractured.
As a extra bit, here is the code I use. I shamelessly copied elements of this pattern from one of Google's examples.
The user can ask for help using a menu item:
For the event (in this case, the event fired when the user clicks on the Help menu item):
I have a singleton called Mediator in which ALL events are registered:
Every event is mated with a Command object to do the work:
Everything is decoupled. The menu widget is bound to a command that executes and then completes. The command fires the event on the bus then completes. The event fires off the execution of a Command and the completes. The Command shows the popup help panel (in this case, an "unimplemented" message to the user -- yeah, I'll get to it soon). Every interaction with a user's input is handled extremely quickly and resolves. It can kick off a series of events to perform a long action, but never tying up the GUI to do so. And of course, since the elements are decoupled, I can call the same elements in other places (for instance, call the help Command through a button push as well as a menu item).