1

我正在尝试访问 ui:binder 组件中的一些对象,但不确定如何访问 eventBus、requestFactory 等而不编写让我彻夜难眠的讨厌代码(另请注意,我对JAVA,背景是 Perl/Python/PHP)。

我的 ui.xml 文件:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'
    xmlns:ig='urn:import:com.ig.client.scaffold.ui.widget'>
    <ui:style>
        ...
    </ui:style>
    <g:HorizontalPanel>
        ...
    </g:HorizontalPanel>
</ui:UiBinder>

以这种方式注入 eventBus 失败,com.ig.client.scaffold.ui.widget.R 没有默认(零参数)构造函数。

public class R extends Composite {

    interface MyUiBinder extends UiBinder<Widget, R> {}
    private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

    private final EventBus eventBus;

    @UiField SimplePanel fieldA, ...;

    @Inject
    public R(EventBus eventBus){
        this.eventBus = eventBus;
        initWidget(uiBinder.createAndBindUi(this));
    }
}

因此,根据错误消息,我创建了一个 UIFactory,然后我收到一个错误... '{style.entityComponent}'> missing required attribute(s): eventBus Element ... (似乎它正在尝试查找ui:binder 样式表中的 eventBus。

public class R extends Composite {

    interface MyUiBinder extends UiBinder<Widget, R> {}
    private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

    private final EventBus eventBus;

    @UiField SimplePanel fieldA, ...;

    public @UiConstructor R(EventBus eventBus){
        this.eventBus = eventBus;
        initWidget(uiBinder.createAndBindUi(this));
    }

    @Inject
    @UiFactory R makeR(){
        return new R(eventBus);
    }
}

从过去几天的阅读和阅读以及更多阅读中,我没有看到任何人直接在绑定到 ui:binder 小部件的视图中访问 eventBus、requestFactory 和 historyController,这导致得出的结论是这可能不是最佳实践反正。

假设我有一个对象,我们称它为 Proxy,proxy 包含 handleButtonClick,然后调用 eventBus.doSomething()。如何将此 Proxy 对象链接到 ui:binder 小部件,而无需实例化它或不必将其传递给每个小部件?

是否可以在接口上进行 GIN 注入,然后通过类 R 实现该接口,然后以某种方式包含我正在寻找的对象?

欢迎任何可行的解决方案,只需寻找一个示例(Java n00b 可以理解),它基本上可以让我将前端与 ROO 创建的其他服务连接起来。

谢谢J

4

1 回答 1

2

查看模型、视图、演示者模式——它解决了这个问题。通常,所有非显示逻辑都应保留在您的视图之外,以便 1) 非显示逻辑可以进行单元测试,而无需在(实例化缓慢的)浏览器中运行,以及 2) 不同的显示可以插入同一个应用程序而无需复制非显示逻辑。

这是一个展示您正在寻找的行为的 MVP 示例(请注意,该样式与“活动和地点”实现略有不同)。

MyPresenter.java:

public class MyPresenter {
  public interface Display extends IsWidget {
    void setButtonClickHandler(ClickHandler buttonClickHandler);
  }

  private final Display display;
  private final EventBus eventBus;

  @Inject
  public MyPresenter(EventBus eventBus,
                     Display display)
  {
    this.display = display;
    this.eventBus = eventBus;

    bind();
  }

  private void bind() {
    display.setButtonClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        eventBus.fireEvent(new MyButtonClickedEvent());
      }
    });
  }

  public void go(HasWidgets container) {
    container.add(display.asWidget());
  }
}

MyView.ui.xml:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
  xmlns:g='urn:import:com.google.gwt.user.client.ui'
  xmlns:ig='urn:import:com.ig.client.scaffold.ui.widget'>

  <g:Button ui:field="myButton"/>
</ui:UiBinder>

我的视图.java

public class MyView extends Composite implements MyPresenter.Display {
  interface MyViewUiBinder extends UiBinder<Widget, MyView> {}
  private static MyViewUiBinder uiBinder = GWT.Create(MyViewUiBinder.class);

  private ClickHandler buttonClickHandler = null;

  public MyView() {
    initWidget(uiBinder.createAndBindUi(this));
  }

  @UiHandler("myButton")
  void onButtonClick(ClickEvent event) {
    if (buttonClickHandler != null) {
      buttonClickHandler.onClick(event);
    }
  }

  @Override
  public void setButtonClickHandler(ClickHandler buttonClickHandler) {
    this.buttonClickHandler = buttonClickHandler;
  }
}

在您的 GIN 模块中:bind(MyPresenter.Display.class).to(MyView.class);

于 2011-01-09T19:38:16.533 回答