2010-01-29 3 views
5

Если я использую шаблон MVP с GWT, как в передовой практике архитектуры GWT из-за ввода-вывода Google с 2009 года, но распространяют информацию на несколько виджетов, как должен объект ценности быть населенным?MVP и связь между виджетами GWT

Скажем, у меня есть EditPersonView/Presenter, EditPetView/Presenter и EditAddressView/Presenter, а последние два являются виджетами как часть панели в EditPersonView. С этим у меня есть следующий класс:

class PersonDetails { 
    private PetDetails pet; 
    private AddressDetails addressDetails; 

    // ... 
} 

PetDetails и переменное AddressDetails экземпляра управляются в их ведущих коллегах. Когда пользователь нажимает кнопку «Сохранить» в EditPersonView, как должна выполняться связь между виджетами, чтобы PersonDetails заполнялась информацией из дочерних виджетов?

ответ

1

Я столкнулся с этой же проблемой в нескольких разных приложениях GWT, которые я разработал с использованием подхода Рей Райана. Мое предпочтительное решение - создать «объект сеанса» Singleton, который сохраняет состояние этой части приложения. В вашем примере, это может выглядеть следующим образом:

interface EditPersonSession { 

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

} 

Все три Ведущих содержит ссылку на объект сессии (возможно, впрыскиваемый Gin). Всякий раз, когда пользовательский интерфейс (представление) манипулируется пользователем, ведущий, связанный с этим представлением, немедленно подталкивает состояние к общему объекту сеанса. Например, внутри 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.

+0

Хм .. Интересное решение. Я не сумасшедший, так это тот факт, что мне нужно будет регистрировать обработчики изменения значений для всех элементов, которые могут не получить мне представление моментального снимка диалога, как если бы я получал значения при выполнении вызова метода editPersonSession.save() , Но я думаю, что так и будет. Благодаря! :) – Arthur

+0

Без проблем :). Пока вы убедитесь, что вы нажимаете значения от докладчиков на объект сеанса, как только изменяется какое-либо значение в представлениях, объект сеанса должен всегда иметь обновленное представление данных в представлениях при вызове спасти(). – Daniel

3

Если вы посмотрите на страницу 42 из presentation Ray Ryan из Google IO 2009, вы должны найти решение своего вопроса. Вы используете «шину событий» (общий экземпляр HandlerManager) и запускаете свое обычное событие PetDetailsChangedEvent и слушаете это событие из дочерних виджетов (стр. 45). Кроме того, помните, что в то время как развязка и т. Д. Велика и все, некоторая муфта не плохая вещь и на самом деле может быть лучшим решением, чем пытаться заставить все быть слабо связанными - RR так говорит в этой презентации :)

+0

Да, я вижу, как ответ от сервера может быть распространен в приложении через событие. Тем не менее, мне сложно найти решение по-другому, это сбор информации из разных виджетов, а затем отправка вызова «savePerson» RPC. Единственные примеры, которые я нашел, довольно тривиальны с помощью метода getName() в представлении, например. – Arthur

+0

Вы можете синхронизировать разные объекты на клиенте с той же шиной событий.Каждое изменение объекта (например, с помощью метода setter) вызывает событие «modelChange», которое прослушивает все задействованные виджеты. Затем они обновляют объект. К тому моменту, когда вы должны отправить вызов «savePerson», все они синхронизированы. – Bluu

+1

Я согласен с комментарием Блю. Однако, в зависимости от приложения, вы можете немного изменить свой подход - сначала вы можете сохранить новые данные на сервере, а затем оттуда выпустить тип события «modelChanged» (например, с помощью cometd, ape- сервер или push-модуль для nginx). Вы бы получили то, что, если у вас есть много экземпляров приложения, открытых на разных вкладках в браузере, все они синхронизируются (полезно для таких вещей, как чат, почта и т. Д. Клиенты - все зависит от того, как ваши пользователи будут использовать ваше приложение) , –

0

Я также пришел к выводу, что у меня может быть одна модель, соответствующая каждому ведущему. Таким образом, PetWidget может создать экземпляр Pet, а PersonWidget может создать экземпляр Person. Затем PersonWidget может содержать один или несколько PetWidgets, что, в свою очередь, означает, что класс Person может иметь список экземпляров Pet.