【问题标题】:Update Panel content when ListBox in other Panel changes当其他 Panel 中的 ListBox 发生变化时更新 Panel 内容
【发布时间】:2024-04-13 19:05:02
【问题描述】:

我是 GWT 的新手。

我在两个不同的面板中有两个ListBox 元素(我们称它们为AB)(如果重要的话,准确地说是CompositeVerticalPanel;我们称它们为panelApanelB)它们有一个共同的父级 (parentPanel)。
我想在 B 更改时更新 A 中的项目列表。

如何在 GWT 中做到这一点?
我的第一个想法是将changeHandler 添加到B,我在A 上调用了一些公共updateItems() 方法。
然而,panelA 根本无法从panelB 访问。更糟糕的是ApanelA 的私有内部类。

我可能可以公开所有这些类/方法等以使其正常工作,但我觉得这不是正确的方法。
我的设计不好吗?在 GWT 中做这些事情的正确方法是什么?我想我只是缺少一个关键字来开始研究......

任何帮助将不胜感激。不要求代码,只是一般概念或建议。

【问题讨论】:

  • 如果应用程序设计遵循 MVP 模式,您将拥有一个演示者来控制当前视图并可以访问所有组件,从而可以更新其组件。
  • 抱歉回复晚了。我将阅读 MVP 并验证它是否在我正在处理的应用程序中使用,但这必须等到明天,因为我现在无法访问此代码。
  • 已检查。这是遗留代码,根本不使用 MVP。还有其他解决方案吗?我们使用的 GWT 版本是 2.40。

标签: java gwt event-handling panel


【解决方案1】:

使用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;
    }

}

在具有 ListBoxA 的 panelA 中,您按如下方式注册事件

ListBoxBEvent.register(eventBus, new ListBoxBEvent.Handler() {
            @Override
            public void onListBoxBChanged (ListBoxBEvent listBoxBEvent) {
                Object seletetObject =  listBoxBEvent.getSelectedObject();
                updateListBoxB(seletetObject);
            }           
        }); 

ListBoxBOnChange 事件中,您触发ListBoxBEvent

view.getListBoxB().addChangeHandler(new ChangeHandler() {
    @Override
    public void onChange(ChangeEvent event) {
       eventBus.fireEvent(new ListBoxBEvent(selectedObject));
    }
});

确保您通过应用程序使用 Singleton 或 DI 使用 EventBus 对象的一个​​实例

【讨论】:

  • 据我所知,EventBus 概念也是 MVP 架构的一部分。即使我不能使用 MVP,您是否建议实施它?
  • 我最终使用了这个解决方案,几乎没有修改。真的很容易添加,即使是遗留代码。
  • Eventbus 不是特定于 MVP 或 GWT 的,可以单独实现(就像您所做的那样)。
【解决方案2】:

使用您的活动/演示者来推动这些变化。例如,在您的 Activity/Presenter 中:

myView.getListBoxB().addChangeHandler(new ChangeHandler() {

    @Override
    public void onChange(ChangeEvent event) {
        updateListBoxA();
    }
});

private void updateListBoxA() {
    ListBox listBoxA = myView.getListBoxA();
    // do what is necessary
}

您也可以在 ParentPanel 小部件中执行此操作。这完全取决于您遵循哪种设计模式。

【讨论】:

  • 感谢您的建议。不幸的是,我无法将 ChangeHandler 添加到 PanelB,因为它只是一个 VerticalPanelPanelB 具有内部类,其属性为 B,类型为 ListBoxB 需要附加处理程序...
【解决方案3】:

正如 Moh 所说,您必须使用 MVP 架构,请参阅:official documentation,演示者必须有权访问您的 A 和 B 抛出 panelA 和 panelB,然后绑定您的 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 ...

那么你的 View 必须实现 MyPresenter.Display 接口。

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.

【讨论】:

  • 不幸的是,我正在处理的代码很大,并且没有使用 MVP。还有其他建议吗?
最近更新 更多