我是GWT的新手。
我在两个不同的Composite
面板中有两个ListBox
元素(我们称它们为 A
和 B
)VerticalPanel
如果这很重要;我们称它们为 panelA
和 panelB
),它们有一个共同的父元素(parentPanel
)。
我想在A
中更新项目列表,当B
更改时。
如何在 GWT 中执行此操作?
我的第一个想法是将changeHandler
添加到B
中,我在其中调用了一些公共updateItems()
方法A
。
霍维尔,panelA
根本无法从panelB
进入。更糟糕的是A
是私人内部阶级panelA
。
我可能可以将所有这些类/方法等公开以使其正常工作,但我觉得这不是正确的方法。
我的设计不好吗?在GWT中做这些事情的正确方法是什么?我想我只是缺少一个开始研究的关键字......
任何帮助将不胜感激。不要求代码,只是一个一般的概念或建议。
使用Eventbus
创建事件
public class ListBoxBEvent extends GwtEvent<ListBoxBChanged.Handler> {
public interface Handler extends EventHandler {
void onListBoxBChanged(ListBoxBEvent listBoxBEvent);
}
public static final GwtEvent.Type<Handler> TYPE = new GwtEvent.Type<Handler>();
private Object selectedObject;
public VueChangedEvent(Object selectedObject) {
this.selectedObject=selectedObject;
}
@Override
public GwtEvent.Type<Handler> getAssociatedType() {
return TYPE;
}
@Override
protected void dispatch(Handler handler) {
handler.onListBoxBChanged(this);
}
public static HandlerRegistration register(EventBus eventBus, Handler handler) {
return eventBus.addHandler(TYPE, handler);
}
public Object getSelectedObject(){
return selectedObject;
}
}
在具有列表框 A 的面板 A 中,您按如下方式注册事件
ListBoxBEvent.register(eventBus, new ListBoxBEvent.Handler() {
@Override
public void onListBoxBChanged (ListBoxBEvent listBoxBEvent) {
Object seletetObject = listBoxBEvent.getSelectedObject();
updateListBoxB(seletetObject);
}
});
OnChange
如果发生ListBoxB
,您将触发ListBoxBEvent
view.getListBoxB().addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
eventBus.fireEvent(new ListBoxBEvent(selectedObject));
}
});
请确保使用单一实例或 DI 通过应用程序使用事件总线对象的一个实例
使用活动/演示者来推动这些更改。例如,在活动/演示者中:
myView.getListBoxB().addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
updateListBoxA();
}
});
private void updateListBoxA() {
ListBox listBoxA = myView.getListBoxA();
// do what is necessary
}
您也可以在父面板小部件中执行此操作。这完全取决于您遵循的设计模式。
正如Moh所提到的,你必须使用MVP架构,参见:官方文档,演示者必须有权访问你的A&B抛出面板A和面板B,然后绑定你的A。例如:
public class MyPresenter {
public interface Display {
CheckBox getA();/* get button A to bind it to appropriate action */
CheckBox getB(); /* get B to update it */
//.......other thing you want get from you View
} // end of interface
private Display display;
/*
* you presenter logic ..
*/
//constructor and initialisation ...
public MyPresenter (Display display/*, MyService myService ..,.. refer to doc*/){
this.diplay=display;
}
private void bind(){
display.getA().addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
//access B by : then update it:: display.getB();
}
});
}//end bind().
// other staff ...
那么你的视图必须实现我的演示者.显示接口。
public class MyView extends /*SomeClass*/ implements MyPresenter.Display{
/* view logic, you must to refactor you code logic to be "more conform" to best practice
see also the example in the doc */
then you have to implement missing methods ( getA and getB ) ( or your widget) that make available you buttons to the presenter.