简体   繁体   English

为多个附加的gwt小部件区分事件

[英]Differentiate events for multiple attached gwt widgets

I've been trying to make multiple Presenters "listen" to the same event but I which to make each event unique to the Presenter. 我一直试图使多个演示者“监听”同一事件,但是我想使每个事件对于演示者都是唯一的。

Ex. 防爆。 I create 3 Composite widgets each in one different tab. 我在一个不同的选项卡中分别创建了3个Composite小部件。 They get all attached to the same event at binding. 它们在绑定时都绑定到同一事件。 Let's call it the "NewPrescriptionEvent". 我们称之为“ NewPrescriptionEvent”。 If this event is fired, all my 3 composites will try to DO the job. 如果该事件被触发,我所有的3层复合材料将尝试的工作。 I only want one of them to do it. 我只希望其中一个可以做到。

The only way I found to do this is by creating a temp event id (an integer inside the event) which I check for each widget which is trying to respond to the event. 我发现这样做的唯一方法是创建一个临时事件ID(事件内部的整数),我检查每个试图响应该事件的小部件。

Code snippet 程式码片段

private class OnNewPrescription implements NewPrescriptionHandler {

    @Override
    public void onNewPrescription(NewPrescriptionEvent event, int dataObjectId) {

        if (getDataObject().getPatientId() == dataObjectId) {
        ...
        }
    }
}

During binding I do the usual: 在绑定期间,我通常执行以下操作:

eventBus.addHandler(NewPrescriptionEvent.TYPE, new OnNewPrescription());

The event: 事件:

public class NewPrescriptionEvent extends GwtEvent<NewPrescriptionHandler> {

    public static final GwtEvent.Type<NewPrescriptionHandler> TYPE = new GwtEvent.Type<NewPrescriptionHandler>();

    private int dataObjectId;

    public NewPrescriptionEvent(int dataObjectId) {
        this.dataObjectId = dataObjectId; 
    }

    @Override
    protected void dispatch(NewPrescriptionHandler handler) {
        handler.onNewPrescription(this, dataObjectId);      
    }

    @Override
    public GwtEvent.Type<NewPrescriptionHandler> getAssociatedType() {
        return TYPE;
    }
}

I was thinking that the TYPE need to be different each time but still be the same event. 我当时以为TYPE每次都需要不同,但仍然是同一事件。 Does anyone have a suggestion? 有人有建议吗?

Thx. 谢谢。

Is it the case that you have an arbitrary number of instances of the same presenter and all are listening to the same event type? 您是否有任意数量的同一演示者实例并且所有人都在侦听同一事件类型? And each of your presenters 'controls' a different entity an therefore should only react on events coming from that entity? 并且您的每个演示者都“控制”一个不同的实体,因此仅应对来自该实体的事件做出反应? If that's the case the only solution I see is to parametrize the event as you've done. 如果是这样的话,我看到的唯一解决方案是按照完成的步骤对事件进行参数化。

Sounds like the EventBus probably isn't the best approach here; 听起来, EventBus可能不是这里的最佳方法。 this is one of the main problems I've personally had with the EventBus : all events are global, and it's hard to differentiate between different events of a given type. 这是我个人对EventBus遇到的主要问题EventBus :所有事件都是全局的,很难区分给定类型的不同事件。

A good set of rules for asynchronous event handling without a shared EventBus is: 没有共享EventBus异步事件处理的一组好的规则是:

  • Communicate with child widgets via direct method calls. 通过直接方法调用与子窗口小部件进行通信。
  • Communicate with a parent widget via callbacks/handlers/listeners. 通过回调/处理程序/侦听器与父窗口小部件通信。
  • Avoid direct knowledge of sibling widgets (probably beside the point here) 避免直接了解同级小部件(可能与此处无关)

So, the widget that contains the 3 tabs can attach callbacks to each tab that, when called, dispatches each event to its appropriate event handler (Presenters, in your case, I believe). 因此,包含3个选项卡的小部件可以将回调函数附加到每个选项卡上,这些选项卡在被调用时会将每个事件分派到其相应的事件处理程序(Presenters,就您而言)。

No global communication required, no knowledge of sources or destinations, only one event type, one reusable tab widget type, and the tab class stays simple. 不需要全局通信,不了解源或目的地,仅一种事件类型,一种可重用的选项卡小部件类型,并且选项卡类保持简单。 In principle, not too different from adding a ValueChangeHandler to a CheckBox (after all, one doesn't subscribe to check box events via the event bus, you just add a handler directly to the widget). 原则上,与将ValueChangeHandler添加到CheckBox没什么不同(毕竟,它不通过事件总线订阅复选框事件,您只需将处理程序直接添加到小部件即可)。

Rough sketch: 草图:

public class TabContainer implements IsWidget {
  public TabContainer() {
    tab1.addNewPrescriptionHandler(
        new NewPrescriptionEventHandler() {
          @Override
          public void handleNewPrescriptionEvent(NewPrescriptionEvent event) {
            handleTab1Event(event);
          }
        });
    tab2.addNewPrescriptionHandler(
        new NewPrescriptionEventHandler() {
          @Override
          public void handleNewPrescriptionEvent(NewPrescriptionEvent event) {
            handleTab2Event(event);
          }
        });
    ...
  }
}

And you might even be able to simplify that with some looping and pairing. 您甚至可以通过一些循环和配对来简化此操作。

Going the other way, this container can also send events back the other way to your widgets from wherever else using the same principles. 走另一条路,这个容器也可以发送事件的其他方式,从其他任何地方使用相同的原则, 回到你的小部件。

Also, depending on what the Event class contains, you might not even need an Event class; 另外,根据Event类包含的内容,您甚至可能不需要Event类。 you can define your callbacks and params however you want. 您可以根据需要定义回调和参数。

I think the title of the question is your answer. 我认为问题的标题就是你的答案。

You need different event types for each of the widgets. 每个小部件都需要不同的事件类型。

You could try using addHandlerToSource(GwtEvent.Type<H> type, Object source, H handler) if you know the source to listen to. 如果您知道要侦听的源,则可以尝试使用addHandlerToSource(GwtEvent.Type<H> type, Object source, H handler)

Another possibility would be to extend EventBus to accept some kind of filter on registration. 另一种可能性是扩展EventBus以在注册时接受某种过滤器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM