@UiHandler方法中的GWT Null对象
我将GWT2.4与MVP一起使用。 这是我的视图对象:@UiHandler方法中的GWT Null对象,gwt,mvp,uibinder,Gwt,Mvp,Uibinder,我将GWT2.4与MVP一起使用。 这是我的视图对象: public class LoginWidget extends Composite implements LoginWidgetView { interface Binder extends UiBinder<Widget, LoginWidget> { } private static final Binder BINDER = GWT.create(Binder.class); @UiField Anchor set
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;
}
LoginWidgetPresenter当然实现视图的Presenter接口。但是,当我单击设置锚点时,presenter引用仍然为null,因此presenter.showSettings()抛出一个NullPointerException。
我假设在调用LoginWidget的构造函数并通过
initWidget(BINDER.createAndBindUi(this));
my@UiHandler(“设置”)方法中的单击处理代码忽略对所用对象(如my presenter对象)的更改??
调用initWidget()方法后,是否有方法设置presenter对象?
或者是否可以自定义@UiHandler/initWidget()-行为,我可以在之后设置演示者
谢谢,Manuel,我用另一种方式实现MVP,UIBinder为我的客户服务。如果在LoginWidget构造函数中传递LoginWidgetPresenter,它可能会工作
public LoginWidget(Presenter presenter) {
this.presenter = presenter;
initWidget(BINDER.createAndBindUi(this));
}
...
getLoginWidget(new LoginWidgetPresenter(placeController));
有很多事情可能出了差错。最简单的方法是尝试调试代码,方法是放置断点
handleSettings
和“setPresenter”方法。
我的猜测是发生了以下情况之一:
从未实际调用过setPresenter
始终返回小部件的新实例,很可能您正在登录小部件的一个实例上设置presenter,但显示的是完全不同的小部件实例getLoginWidget()
- 您的代码中有
getLoginWidget().setPresenter(null)
或者其他任何猜测。调试和查看presenter实例的传递位置和方式要容易得多。无论如何,
UiBinder
不会删除您的字段值(除非被其他人修改以取笑您)谢谢您的回答。但是在您的方法中,您必须了解在创建小部件时将其传递到构造函数中的placeController(或者可选的请求工厂)。如果我想在另一个视图组件中创建小部件,我必须使请求工厂和放置控制器在那里可用,我想这不是MVP推荐的吗?或者我错过了什么…你调试过了吗?在setPresenter
和handleSettingsClick
中都有断点,并确保在相同的LoginWidget
实例上以正确的顺序调用断点?谢谢您的回答。我已经调试过了<代码>setPresenter()通过真实的presenter实例调用。但是在handleSettingsClick()
中,组件的presenter
类变量为空。因此,我认为它必须是一个不同的LoginWidget
实例,我在其上设置了presenter
。但这正是我要寻找的。我只是想确保它正常工作,我已经实现了。谢谢你的回答。正如我在上面的评论中提到的,我已经调试过了<在通过延迟绑定创建LoginWidget
后,调用code>setPresenter。getLoginWidget
只是父UI组件上的一个简单的get方法(LoginWidget
只是父组件上的一个@UiField
),因此实际上不能再有LoginWidget
的实例了。父组件实现为单例。但是在上面的评论中,很高兴知道@UiHandler
应该支持在调用initWidget(…)
之后设置presenter对象。@TonySkulk好吧,我只能说一件事。从您提供的代码中,我看不出有任何问题。标准的普通UiBinder无法对私有字段执行任何操作。顺便问一下,你是怎么调试的?您是否将断点同时设置为setPresenter
和handleSettingsClick
并验证了它们都是以正确的顺序调用的,并且“setPresenter是以正确的值调用的?”是的,我正在使用Eclipse/STS并在这两种方法中设置断点<使用正确的Presenter
实例调用code>setPresenter。在handleSettingsClick
中,privatepresenter
字段为空。@TonySkulk您是否可以创建一个小的工作示例项目来演示这个问题?因为它肯定是由某些东西引起的,在你的问题中它没有被证明。唯一的情况(假设您没有忽略某些内容)是,实际上有一些JSNI代码可以直接删除presenter字段。我在我的EntryPoint
类中找到了一个调用setPresenter
的解决方法。虽然将演示者注入组件可能应该在相应活动的构造函数中完成,但我无法理解为什么它在那里不起作用。即使我添加了一个只调用LoginWidget
的setPresenter
方法的按钮,presenter仍将为空。
public LoginWidget(Presenter presenter) {
this.presenter = presenter;
initWidget(BINDER.createAndBindUi(this));
}
...
getLoginWidget(new LoginWidgetPresenter(placeController));