简体   繁体   English

MVP和GWT小部件之间的通信

[英]MVP and communication between GWT widgets

If I am using the MVP pattern with GWT, as in the GWT architecture best practices talk from Google I/O from 2009, but have spread out the information into multiple widgets, how should the value object be populated? 如果我在GWT中使用MVP模式,就像在GWT架构中从2009年的Google I / O谈起最佳实践,但是将信息分散到多个小部件中,应该如何填充值对象?

Say I have a EditPersonView/Presenter, a EditPetView/Presenter and an EditAddressView/Presenter and the last two are widgets as a part of a panel in the EditPersonView. 假设我有一个EditPersonView / Presenter,一个EditPetView / Presenter和一个EditAddressView / Presenter,最后两个是小部件,作为EditPersonView中面板的一部分。 With these I have the following class: 有了这些我有以下课程:

class PersonDetails {
    private PetDetails pet;
    private AddressDetails addressDetails;

    // ...
}

The PetDetails and AddressDetails instance variables are managed in their presenter counterparts. PetDetails和AddressDetails实例变量在其演示者对应物中进行管理。 When the user clicks the "Save" button in the EditPersonView, how should the communication between the widgets be done so that the PersonDetails is filled with information from its child widgets? 当用户单击EditPersonView中的“保存”按钮时,如何完成窗口小部件之间的通信,以便PersonDetails充满来自其子窗口小部件的信息?

If you look at page 42 of the presentation by Ray Ryan from Google IO 2009 you should find the solution to your question. 如果您查看来自Google IO 2009的Ray Ryan 演示文稿的第42页,您应该找到问题的解决方案。 You use an "event bus" (shared instance of HandlerManager ) and fire your custom PetDetailsChangedEvent event and listen for that event from your child widgets (page 45). 您使用“事件总线”( HandlerManager共享实例)并触发自定义PetDetailsChangedEvent事件并从子窗口小部件中侦听该事件(第45页)。 Also, remember that while decoupling, etc is great and all, some coupling is not a bad thing and might actually be a better solution than trying to force everything to be loosely coupled - RR says so in that presentation himself :) 此外,请记住,虽然解耦等等很好,但是一些耦合并不是坏事,实际上可能是一个比试图强制松散耦合的更好的解决方案--RR在演示中自己说:)

I've faced this same problem in a few different GWT applications that I've designed using Ray Ryan's approach. 我在使用Ray Ryan的方法设计的一些不同的GWT应用程序中遇到了同样的问题。 My preferred solution is to create a Singleton "session object" that stores the state of that part of the application. 我首选的解决方案是创建一个Singleton“会话对象”,用于存储应用程序该部分的状态。 In your example, it might look like this: 在您的示例中,它可能如下所示:

interface EditPersonSession {

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

}

All three presenters contain a reference to the session object (perhaps injected by Gin). 所有三个演示者都包含对会话对象的引用(可能由Gin注入)。 Whenever the UI (view) is manipulated by the user, the presenter associated with that view immediately pushes the state to the shared session object. 每当用户操纵UI(视图)时,与该视图关联的演示者立即将状态推送到共享会话对象。 For example, inside EditAddressPresenter: 例如,在EditAddressPresenter中:

view.getStreetNameTextBox().addValueChangeHandler(new ValueChangeHandler() {

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

}

When it is time to save, the state object is told to save the state to the server. 在保存时,状态对象被告知将状态保存到服务器。 At this point, the session object has up-to-date representations of the data, and can save it all at once. 此时,会话对象具有数据的最新表示,并且可以一次性保存所有数据。 So, in EditPersonPresenter: 所以,在EditPersonPresenter中:

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

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

}

This way, the presenters need not contain any references to each other, but can send consistent information to the server. 这样,演示者不需要包含对彼此的任何引用,但可以向服务器发送一致的信息。 If the presenters need to know when information that they display has been updated (either by other presenters, or by the server), the session object can notify them by firing events on the event bus (shared Singleton HandlerManager). 如果演示者需要知道他们显示的信息何时更新(由其他演示者或服务器),会话对象可以通过触发事件总线上的事件(共享Singleton HandlerManager)来通知他们。 The presenters can then pull the most current PersonDetails from the session object. 然后,演示者可以从会话对象中提取最新的PersonDetails。

I've also come to the conclusion that I can have one model that corresponds to each presenter. 我还得出结论,我可以拥有一个与每个演示者相对应的模型。 So a PetWidget may create a Pet instance and a PersonWidget may create a Person instance. 因此,PetWidget可以创建Pet实例,PersonWidget可以创建Person实例。 The PersonWidget may then contain one or more PetWidgets which in turn means that the Person class can have a list of Pet instances. PersonWidget然后可以包含一个或多个PetWidgets,这反过来意味着Person类可以具有Pet实例的列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM