GWT,如何使用来自 HandlerManager 的 EventBus 从小部件或复合材料触发事件

GWT, how to fire event from widget or composite using EventBus from HandlerManager

我有小部件。我想触发一个事件如下:

fireEvent(new IndicatorStartEvent("Message"));

但是没用。

通常我为此使用 Presenter (GWTP),但现在我只想使用常规小部件:

public class FileUploadWidget extends Composite {
    MaterialFileUploader uploader = new MaterialFileUploader();

    @Inject
    public FileUploadWidget(String triggerId, EventBus eventBus) {
        super();
        initWidget(uploader);
        Window.alert("TEST Start");
        fireEvent(new IndicatorStartEvent("Message"));
    }
}

这是事件代码:

public class IndicatorStartEvent extends GwtEvent<IndicatorStartEvent.IndicatorHandler> {
    public static Type<IndicatorHandler> TYPE = new Type<IndicatorHandler>();

    public interface IndicatorHandler extends EventHandler {
        void onIndicatorProgressStart(IndicatorStartEvent event);    
    }

    public interface IndicatorHandlers extends HasHandlers {
        HandlerRegistration addStartIndicatorHandler(IndicatorHandler handler);
    }


    private final String message;

    public IndicatorStartEvent(final String message) {
        this.message = message;
    }

    public static Type<IndicatorHandler> getType() {
        return TYPE;
    }

    @Override
    protected void dispatch(final IndicatorHandler handler) {
        handler.onIndicatorProgressStart(this);
    }

    @Override
    public Type<IndicatorHandler> getAssociatedType() {
        return TYPE;
    }

    public String getMessage() {
        return this.message;
    }    
}

这是我处理事件的应用演示者:

public class AppPresenter extends TabContainerPresenter<AppPresenter.MyView, AppPresenter.MyProxy> implements AppUiHandlers
, IndicatorStartEvent.IndicatorHandler {
    @ProxyStandard
    public interface MyProxy extends Proxy<AppPresenter> {}
    public interface MyView extends TabView, HasUiHandlers<AppUiHandlers> {}
    @Override
    protected void onBind() {
        super.onBind();
        addRegisteredHandler(IndicatorStartEvent.getType(), this);
    }

    public void onAsyncCallFail(AsyncCallFailEvent event) {
    // fireEvent is executed from: com.gwtplatform.mvp.client;PresenterWidget
        fireEvent(new IndicatorStartEvent("Firing message"));
    }

    @Override
    public void onIndicatorProgressStart(IndicatorStartEvent event) {
        MaterialToast.fireToast("Indicator start: " + event.getMessage());
    }
}

如果我从 f.e 触发此事件:AppPresenter(上面的代码),或 GwtRESTY filter/callback ass follow:

class ProgressIndicatorFilter implements DispatcherFilter {
    private AssistedInjectionFactory factory;
    private EventBus eventBus;

    @Inject
    public ProgressIndicatorFilter(AssistedInjectionFactory factory, EventBus eventBus) {
        this.factory = factory;
        this.eventBus = eventBus;
    }
    @Override
    public boolean filter(Method method, RequestBuilder builder) {
        builder.setCallback(factory.createProgressIndicatorCallback(method));
        eventBus.fireEvent(new IndicatorStartEvent("Rest-Gwt Comunication started"));
        return true;
    }
}

它按预期工作。但在那些工作示例中,它使用 com.google.web.bindery.event.shared;EventBus 触发事件不适用于小部件,其中使用: com.google.gwt.event.shared;HandlerManager;Bus class。 class Bus extends com.google.web.bindery.event.shared.SimpleEventBuscom.google.web.bindery.event.shared;EventBus.

扩展了正确的 EventBus class

因此小部件的方法 fireEvent() 使用其他 EventBus

谁能帮我解决这个问题?

我红官了,这条指令: http://blog.arcbees.com/2015/04/01/gwt-platform-event-best-practices-revisited/ 但到目前为止运气不好。请帮助。

它不起作用,因为您的 FileUploadWidget 使用它自己的 EventBus 而不是 GWTP 也用于您所有 PresentersGWTP

有两种解决方案:

  1. 不要使用 fireEvent(new IndicatorStartEvent("Message")),而是在 Widget 内注入的 EventBus 上使用 eventBus.fireEvent(new IndicatorStartEvent("Message"))

  2. 直接将 IndicatorStartEvent 处理程序添加到 FileUploadWidget,而不是在 Presenter 上使用 addRegisteredHandler

我更喜欢方案 2:

public class FileUploadWidget extends Composite {
    MaterialFileUploader uploader = new MaterialFileUploader();

    @Inject
    public FileUploadWidget(String triggerId) {
        super();
        initWidget(uploader);
        Window.alert("TEST Start");
        fireEvent(new IndicatorStartEvent("Message"));
    }
}

Presenter 中,或者准确地说是 View 中使用了您的 FileUploadWidget,您直接将处理程序添加到 FileUploadWidget:

public class UploadView extends ViewWithUiHandlers<UploadUiHandlers> implements UploadPresenter.MyView,IndicatorStartEvent.IndicatorHandler {

    @UiField
    FileUploadWidget uploadWidget;

    @Inject
    public UploadView(final Binder binder) {
      widget = binder.createAndBindUi(this);    
      uploadWidget.addHandler(new IndicatorStartEvent.Handler(),this);
    }

    public void onIndicatorProgressStart(IndicatorStartEvent event) {
       MaterialToast.fireToast("Indicator start: " + event.getMessage());
    }
}