Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java MVP和GWT小部件之间的通信_Java_Gwt_Architecture_Mvp - Fatal编程技术网

Java MVP和GWT小部件之间的通信

Java MVP和GWT小部件之间的通信,java,gwt,architecture,mvp,Java,Gwt,Architecture,Mvp,如果我在GWT中使用MVP模式,就像2009年Google I/O中的GWT架构最佳实践演讲一样,但是已经将信息分散到多个小部件中,那么应该如何填充值对象 假设我有一个EditPersonView/Presenter、一个EditPetView/Presenter和一个EditAddressView/Presenter,最后两个是作为EditPersonView中面板一部分的小部件。有了这些,我就有了以下课程: class PersonDetails { private PetDetai

如果我在GWT中使用MVP模式,就像2009年Google I/O中的GWT架构最佳实践演讲一样,但是已经将信息分散到多个小部件中,那么应该如何填充值对象

假设我有一个EditPersonView/Presenter、一个EditPetView/Presenter和一个EditAddressView/Presenter,最后两个是作为EditPersonView中面板一部分的小部件。有了这些,我就有了以下课程:

class PersonDetails {
    private PetDetails pet;
    private AddressDetails addressDetails;

    // ...
}

PetDetails和AddressDetails实例变量在其presenter对应项中进行管理。当用户单击EditPersonView中的“Save”(保存)按钮时,小部件之间的通信应该如何进行,以使PersonDetails中充满来自其子小部件的信息?

如果您查看Google IO 2009中Ray Ryan的第42页,您应该会找到问题的解决方案。您使用一个“事件总线”(HandlerManager的共享实例)并触发自定义的
PetDetailsChangedEvent
事件,并从您的子窗口小部件中侦听该事件(第45页)。另外,请记住,虽然解耦等都很好,但一些耦合并不是坏事,实际上可能是一个比试图强制所有东西都松散耦合更好的解决方案-RR在那篇演讲中这样说:)

我在使用Ray Ryan的方法设计的几个不同GWT应用程序中遇到了同样的问题。 我的首选解决方案是创建一个存储应用程序该部分状态的单例“会话对象”。在您的示例中,它可能如下所示:

interface EditPersonSession {

    void fetchPerson(PersonId id);
    PersonDetails getCurrentPersonDetails();
    void updatePersonDetail(PersonDetail<?> detail);
    void updatePetDetail(PetDetail<?> detail);
    void updateAddressDetail(AddressDetail<?> detail);
    void save();

}
这样,演示者不需要包含彼此的任何引用,但可以向服务器发送一致的信息。
如果演示者需要知道他们显示的信息何时更新(由其他演示者或服务器更新),会话对象可以通过在事件总线(共享单例HandlerManager)上触发事件来通知他们。然后,演示者可以从会话对象中提取最新的个人信息。

我还得出结论,我可以有一个模型对应于每个演示者。因此,PetWidget可以创建Pet实例,PersonWidget可以创建Person实例。PersonWidget可能包含一个或多个PetWidget,这意味着Person类可以有一个Pet实例列表。

是的,我可以看到服务器的响应如何通过事件传播到应用程序。然而,我很难找到另一种解决方案,即从不同的小部件收集信息,然后发送一个“savePerson”RPC调用。我发现的唯一例子就是在视图上使用getName()方法非常简单。您可以使用相同的事件总线在客户端上保持不同对象的同步。让对象的每次更改(例如通过setter方法)触发一个“modelChange”事件,所有相关的小部件都会侦听该事件。然后更新对象。当你必须发送一个“储蓄者”电话时,他们都是同步的。我同意布鲁的评论。但是,根据应用程序的不同,您可能需要稍微改变一下方法-您可以先将新数据保存到服务器,然后再从服务器发出“modelChanged”类型的事件(例如,在cometd、ape服务器或nginx推送模块的帮助下)。你会得到的是,如果你在浏览器的不同选项卡中打开了应用程序的多个实例,它们都会同步(对于聊天、邮件等客户端很有用,这取决于你的用户将如何使用你的应用程序)。我认为,在编辑过程中保持对象与UI同步会产生一个非常“脆弱”的问题对话框和我还需要将事件处理程序附加到所有控件。我想做的是,只要用户单击“保存”,就会收集对话框中的所有数据,然后作为请求发送到服务。我可以在小部件上设置getter,但我认为事件机制可以为我解决这个问题(只需让新的小部件连接到事件总线)。然而,这些条件很难管理。例如,仅当选中复选框时才从控件收集信息。我现在解决此问题的方法是使用PopulatePersonDetailsEvent,对话框中的组件可以处理并填充它们所拥有的信息(例如EditPetView执行一个事件。getPersonDetails().setPetDetails(new PetDetails(…))。然而,我发现这种解决方案很难处理。假设顶部有一个复选框,用于启用/禁用人员编辑视图。复选框的值必须随事件一起传递,因此需要提前获取。嗯。。有趣的解决方案。我不喜欢的是,我需要为所有元素注册值更改处理程序,这些元素可能无法为我获取对话框的快照表示形式,就像我在执行editPersonSession.save()方法调用时获取值一样。但我想可以。谢谢!:)没问题:)。只要确保在视图中的任何值发生更改时立即将值从演示者推送到会话对象,则在调用save()时,会话对象应始终具有视图中数据的最新表示形式。
view.getStreetNameTextBox().addValueChangeHandler(new ValueChangeHandler() {

    void onValueChange(ValueChangeEvent<String> event) {
        editPersonSession.updateAddressDetail(new StreetNameAddressDetail(event.getValue()));
    }

}
view.getSaveButton().addClickHandler(new ClickHandler() {

    void onClick(ClickEvent event) {
        editPersonSession.save();
    }

}