【问题标题】:Spring ROO GWT with GIN injection on widgets created by ui:binder在由 ui:binder 创建的小部件上使用 GIN 注入的 Spring ROO GWT
【发布时间】:2011-01-09 14:56:52
【问题描述】:

我正在尝试访问 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}'> 缺少必需的属性:eventBus 元素 ...(似乎它正在尝试在 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,这导致得出的结论是它可能不是最佳实践 无论如何。

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

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

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

谢谢 J

【问题讨论】:

    标签: gwt spring-roo uibinder gwt-gin


    【解决方案1】:

    查看Model, View, Presenter pattern - 它解决了 这个问题。一般来说,所有非显示逻辑都应该被排除在外 您的意见,以便 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>
    

    MyView.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);

    【讨论】:

    • 感谢 Jason,我今天早上正在阅读 Google Code 的 MVP 文档,它似乎正是我想要的,今晚晚些时候将实现。谢谢一百万:-)
    • 嗨 Jason,我没有让您的示例正常工作,您是否有可用的源代码,或者您介意查看我的代码并指出问题 - 我没有绑定到工作,现在已经挣扎了好几个星期了。
    • 您为什么不针对您遇到的问题提出一个新问题,并从此处的评论中链接到它,以便我看到它?
    • 嗨 Jason,GWT 邮件列表上的某个人帮助我解决了这个问题,不过感谢您为我指明了正确的方向。
    猜你喜欢
    • 2011-06-12
    • 2012-03-16
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多