【问题标题】:GWT Null objects in @UiHandler methods@UiHandler 方法中的 GWT Null 对象
【发布时间】:2012-11-26 16:15:28
【问题描述】:

我正在使用带有 MVP 的 GWT 2.4。 这是我的视图对象:

public class LoginWidget extends Composite implements LoginWidgetView {

interface Binder extends UiBinder<Widget, LoginWidget> {
}

private static final Binder BINDER = GWT.create(Binder.class);

@UiField Anchor settings;

public LoginWidget() {
    initWidget(BINDER.createAndBindUi(this));
}

@UiHandler("settings")
void handleSettingsClick(ClickEvent e) {
    presenter.showSettings();
}

private Presenter presenter;

@Override
public void setPresenter(Presenter presenter) {
    this.presenter = presenter;
}

}

我正在设置视图的演示者

...
getLoginWidget().setPresenter(new LoginWidgetPresenter(placeController));

LoginWidgetPresenter 当然实现了视图的 Presenter 接口。但是当我点击设置锚点时,presenter 引用仍然为 null,因此 presenter.showSettings() 会抛出 NullPointerException。 我想在调用 LoginWidget 的构造函数并通过

初始化小部件之后
initWidget(BINDER.createAndBindUi(this));

@UiHandler("settings") 方法中的点击处理代码会忽略对已使用对象的更改,例如我的演示者对象? 有没有办法在调用 initWidget() 方法后设置 Presenter 对象? 或者是否可以自定义 @UiHandler/initWidget() 行为,然后我可以设置我的演示者?

谢谢,曼努埃尔

【问题讨论】:

  • 你调试了吗?在setPresenterhandleSettingsClick 中都有断点,并确保它们以正确的顺序在同一个LoginWidget 实例上调用?
  • 感谢您的回答。我已经调试过了。 setPresenter() 使用 real 演示者实例调用。但是在handleSettingsClick() 组件的presenter 类变量为空。所以我认为它必须是一个不同的LoginWidget 实例,我在其上设置了presenter。但这正是我必须寻找的。我只是想确保它通常可以正常工作,我已经实现了它。

标签: gwt mvp uibinder


【解决方案1】:

我以另一种方式实现 MVP,而 UIBinder 为我工作。也许如果你在 LoginWidget 构造函数中传递 LoginWidgetPresenter 它会起作用。

public LoginWidget(Presenter presenter) {
    this.presenter = presenter;
    initWidget(BINDER.createAndBindUi(this));
}
...
getLoginWidget(new LoginWidgetPresenter(placeController));

【讨论】:

  • 感谢您的回答。但是在您的方法中,您必须了解在创建小部件时在构造函数中传递它的 placeController(或者可能是可选的请求工厂)。如果我想在另一个视图组件中创建小部件,我必须使请求工厂和放置控制器可用,我认为这不是 MVP 推荐的吗?或者也许我错过了什么......
【解决方案2】:

有很多事情可能会出错。最简单的方法是尝试通过设置断点handleSettings 和“setPresenter”方法来调试您的代码。 我的猜测是以下情况之一正在发生:

  • setPresenter 从未真正被调用过

  • getLoginWidget() 总是返回一个新的小部件实例,你很有可能在登录小部件的一个实例上设置演示者,但显示的小部件实例完全不同

  • 您的代码中有getLoginWidget().setPresenter(null)

或任何其他猜测。调试起来要容易得多,并且自己查看演示者实例的传递位置和方式。无论如何,UiBinder 不会抹去你的字段值(除非被别人修改来取笑你)

【讨论】:

  • 感谢您的回答。正如我在上面的评论中提到的,我已经调试过了。 setPresenter 在通过延迟绑定创建 LoginWidget 后调用。 getLoginWidget 只是父 UI 组件上的一个简单 get 方法(LoginWidget 只是父组件上的 @UiField),所以实际上不能再有 LoginWidget 的实例了。父组件实现为 Singleton。但正如上面的评论,很高兴知道@UiHandler 应该支持在调用initWidget(...) 之后设置我的演示者对象。
  • @TonySkulk 好吧,我只能说一件事。从您提供的代码中,我看不出有什么问题。标准的普通 UiBinder 不能对私有字段做任何事情。顺便问一下,你是怎么调试的?您是否为 setPresenterhandleSettingsClick 设置了断点并验证它们都以正确的顺序调用并且 `setPresenter 以正确的值调用?
  • 是的,我正在使用 Eclipse/STS 并在这两种方法中设置断点。 setPresenter 使用 正确 Presenter 实例调用。在handleSettingsClick 中,私有presenter 字段为空。
  • @TonySkulk 您是否可以创建可以演示此问题的小型工作示例项目?因为它肯定是由某些东西引起的,所以在您的问题中没有体现出来。唯一的情况(假设你没有忽略某些东西)是实际上有一些 JSNI 代码可以直接擦除演示者字段。
  • 我在我的 EntryPoint 班级中找到了一种解决方法,调用 setPresenter。虽然将演示者注入组件可能应该在相应的活动构造函数中完成,但我无法弄清楚为什么它在那里不起作用。即使我添加一个只调用LoginWidgetsetPresenter 方法的按钮,演示者仍然是null
猜你喜欢
  • 2011-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多