Если я использую шаблон MVP с GWT, как в разговоре о лучших практиках архитектуры GWT от Google I/O с 2009, но распространил информацию в несколько виджетов, как значение должно возразить, заполняются?
Скажите, что у меня есть EditPersonView/Presenter, EditPetView/Presenter и EditAddressView/Presenter, и последние два являются виджетами как частью панели в EditPersonView. С ними у меня есть следующий класс:
class PersonDetails {
private PetDetails pet;
private AddressDetails addressDetails;
// ...
}
Переменными экземпляра PetDetails и AddressDetails управляют в их дубликатах предъявителя. Когда пользователь нажимает кнопку "Save" в EditPersonView, как должен коммуникация между виджетами быть сделанным так, чтобы PersonDetails был переполнен информацией от своих дочерних виджетов?
Я столкнулся с той же проблемой в нескольких различных приложениях GWT, которые я разработал с использованием подхода Рэя Райана. Я предпочитаю создать "объект сеанса" синглтона, который хранит состояние этой части приложения. В вашем примере это может выглядеть так:
interface EditPersonSession {
void fetchPerson(PersonId id);
PersonDetails getCurrentPersonDetails();
void updatePersonDetail(PersonDetail<?> detail);
void updatePetDetail(PetDetail<?> detail);
void updateAddressDetail(AddressDetail<?> detail);
void save();
}
Все три презентатора содержат ссылку на объект сеанса (возможно, введенную Джином). Когда пользователь манипулирует пользовательским интерфейсом (представлением), ведущий, связанный с этим представлением, немедленно передает состояние общему объекту сеанса. Например, внутри EditAddressPresenter:
view.getStreetNameTextBox().addValueChangeHandler(new ValueChangeHandler() {
void onValueChange(ValueChangeEvent<String> event) {
editPersonSession.updateAddressDetail(new StreetNameAddressDetail(event.getValue()));
}
}
Когда приходит время сохранять, объекту состояния предлагается сохранить состояние на сервере. На этом этапе объект сеанса имеет актуальные представления данных и может сохранить их все сразу. Итак, в EditPersonPresenter:
view.getSaveButton().addClickHandler(new ClickHandler() {
void onClick(ClickEvent event) {
editPersonSession.save();
}
}
Таким образом, презентаторы не должны содержать никаких ссылок друг на друга, но могут отправлять согласованную информацию на сервер. Если докладчикам необходимо знать, когда информация, которую они отображают, была обновлена (другими докладчиками или сервером), объект сеанса может уведомить их, запустив события на шине событий (общий Singleton HandlerManager). Затем докладчики могут извлечь самые последние PersonDetails из объекта сеанса.
Если вы посмотрите на страницу 42 презентации Рэя Райана из Google IO 2009, вы должны найти решение вашего вопроса. Вы используете "шину событий" (общий экземпляр HandlerManager
) и запускаете пользовательское событие PetDetailsChangedEvent
, а затем прослушиваете его с помощью своих дочерних виджетов (стр. 45). Также помните, что при развязке и т.д., и т.п., соединение некоторое неплохое и на самом деле может быть лучшим решением, чем пытаться заставить все быть свободно соединенным - так говорит сам РР в этой презентации :)
Я также пришел к выводу, что у меня может быть одна модель, соответствующая каждому докладчику. Таким образом, PetWidget может создать экземпляр Pet, а PersonWidget может создать экземпляр Person. В этом случае PersonWidget может содержать один или несколько PetWidget, что, в свою очередь, означает, что класс Person может иметь список экземпляров Pet.