Ведущий модели представления, как передать сущности между представлениями? - PullRequest
8 голосов
/ 10 февраля 2009

Редактировать: Принятый ответ Криса Холмса, но всегда готов к рефакторингу, если кто-то придумает лучший способ! Спасибо!

Выполнение некоторых winforms с MVP, как лучше всего передать объект в другое представление.

Допустим, у меня есть CustomerSearchView/Presenter, на двойной клик я хочу показать CustomerEditView/Presenter. Я не хочу, чтобы мой взгляд знал о модели, поэтому я не могу создать ctor, который принимает ICustomer в параметрах.

Мой рефлекс будет,

CustomerSearchView создайте новый CustomerEditView, который создаст его собственного докладчика. Тогда мой CustomerSearchView будет делать что-то вроде:

var customerEditView = new CustomerEditView();
customerEditView.Presenter.Customer = this.Presenter.SelectedCustomer;

Другим возможным подходом будет класс CustomerDTO и создание CustomerEditView, которые принимают один из этих CustomerDTO, но я думаю, что это большая работа, что-то простое.

Извините за основной вопрос, но все примеры, которые я могу найти, никогда не доходят до этой точки, и это проект в коричневом поле, и используемый до сих пор подход вызывает у меня головную боль ...

Ответы [ 5 ]

4 голосов
/ 11 февраля 2009

Я не знаю точно, как вы показываете свои взгляды, поэтому немного сложно дать вам конкретный совет здесь. Вот как я делал подобные вещи раньше:

Мы сделали так, чтобы CustomerSearchViewPresenter запускал событие, подобное OpenCustomer (customerId). (Это предполагает, что в вашем поисковом представлении есть только несколько фрагментов данных о клиентах, и customerId будет одним из них. Если в вашем поисковом представлении есть целые объекты Customer, вы можете вызвать OpenCustomer (customer). представление поиска и позволяет ему заполняться целыми объектами ... Мы облегчаем поиск с точки зрения данных.)

Где-то еще в приложении есть обработчик событий, который прослушивает событие OpenCustomer () и выполняет задачу создания нового CustomerEditView с Presenter (и я собираюсь сделать так, чтобы мой контейнер IoC сделал это для меня, поэтому мне не нужно нигде использовать ключевое слово "new"). Как только представление создано, мы можем передать идентификатор (или объект клиента) новому CustomerEditView и затем показать его.

Этот класс, который отвечает за перечисление события OpenCustomer () и выполняет создание CustomerEditView, обычно является своего рода классом Controller в нашем приложении.

Чтобы еще больше упростить эту ситуацию, я сделал это по-другому: я создаю как CustomerSearchView (& Presenter), так и CustomerEditView (& Presenter) при запуске приложения или модуля. Когда CustomerSearchView необходимо открыть Customer для редактирования, CustomerEditView становится ответчиком на событие OpenCustomer и загружает данные в себя и знает, как показать себя в любом контейнере, который он должен делать.

Так что есть несколько способов сделать это.

1 голос
/ 10 февраля 2009

Как насчет:

//In CustomerSearchPresenter
var presenter = new CustomerEditPresenter();
var customerEditView = new CustomerEditView(presenter);
presenter.SetCustomer(customer);

//In CustomerEditPresenter
public void SetCustomer(customer)
{
    View.Name = customer.Name;
    View.Id = customer.Id;
    ...
}

Думаю, что ваше представление поиска клиента должно просто делегировать его докладчику, вам нужно выполнить действие.

0 голосов
/ 16 июля 2012

Раньше мои взгляды общались с их докладчиками, но они отошли от этого. Он не соответствует первоначальному определению шаблона (сам по себе не является причиной отклонения только способствующего фактора для получения этих преимуществ). В идеале представления должны быть как можно более тупыми и иметь как можно меньше зависимостей. View должен общаться с Presenter (любыми «наблюдателями») через делегатов / события / какой-то механизм «запускай и забывай». На самом деле, я ввел контроллер в MVP специально для перехвата событий View и либо перезапуска докладчика (редко) для связи с Presenter, либо для связи с системой или шиной событий, специфичной для Presenter - что позволяет мне изменить механизмы оповещения о действиях пользователя, не касаясь вида. Должны быть осторожны с шиной событий, хотя; довольно скоро вы начинаете добавлять туда все события, приложение начинает болтать / увязать в обработке событий, а события - не самые быстрые вещи в .Net. Сунхронизация - это дополнительная проблема, особенно если вашему приложению требуется более «диалоговое» взаимодействие с вашим пользователем.

Следует иметь в виду, что, хотя Presenter является обычным представлением / специфичным для процесса, представления (и модели представлений) могут использоваться повторно; наличие представления в отношениях сдерживания / делегирования с докладчиком сильно связывает представление / ограничивает его повторное использование. Это может быть уменьшено некоторыми DI, но я нахожу DI-контейнеры ненужной сложностью в большинстве случаев (поскольку мне все равно нужно знать, как создавать объекты и как часто вы заменяете объект на другой семантически похожий объект после его создания / тестирования). ?). Конкретная зависимость не идет никуда, кроме другого слоя / добавляет больше неясности / усложняет отладку / трассировку. Впрочем, в последнее время мы были в «простоте», и в большинстве своем предпочитаю делать сопоставления на объектах / созданиях объектов / ORM для большинства приложений, так как обычно используются таблицы / сущности «1-к-1» между двумя базами данных и не требуется добавление Сложность универсального стороннего инструмента ORM, который в силу общего контекста / необходимости обслуживать разные приложения должен усложнять работу, даже если вы понимаете, как они работают (не в этом суть).

Более того, для View все еще вполне возможно наблюдать Модель в MVP (как в MVC), поэтому я не буду так быстро исключать это. Я не предпочитаю делать это сам, но это «не нарушает» шаблон. Фактически, я разработал нечто похожее на MVP около десяти лет назад, потому что мне не нравился «круговой цикл» между компонентами MVC (View, зная о Model); Я предпочел иметь более чистое разделение между View и Model, которое исповедуют все эти шаблоны (включая MVC), а также желание сохранять View как можно более тупым (наблюдение за Model будет означать, что View потребуется больше интеллекта для обработки изменений в модели). В итоге я сделал что-то вроде MVVM и паттерна стратегии, где я использовал «подструктуры» модели для передачи в View, выступая в качестве «уведомителей об изменениях». Это позволяло видеть все цели для конкретных целей и гибко / многоразово (жесткая комбинация).

0 голосов
/ 21 мая 2012
  1. Я бы посмотрел на MS Prism 4 и их приятный навигационный интерфейс. Также посмотрите на Silverlight и WCF Navigation. Они хорошо сделаны и обрабатывают такие вещи, как запрос пользователя на подтверждение от «грязных» форм с отменой.

  2. Я бы также посмотрел документацию PageFunction () в WCF, чтобы узнать, как «вызвать» страницу с другой и получить информацию назад.

Вот как это работает (JavaScript, извините):

Пользователь дважды щелкает клиента в списке клиентов:

CustomerList.onDblClick(customerId){

  app.fireEvent('customerEditRequest', id)

}

...

app.onCustomerEditRequest(id){
  this.mainRegion.requestNavigate('customers/edit', id);
}

Если навигация для редактирования вида прошла успешно ...

CustomerEditView.onNavigatedTo(context){
  this.model.load(context.parameters.id));
}

CustomerEditView.onSaveButtonClick(){
  this.model.save();
  app.fireEvent('customerEdited', id);
}

...

app.onCustomerEdited(id){
  app.mainRegion.requestNavigate('customerlist', id);
}

Есть несколько способов сделать это:

  1. отправить функцию обратного вызова в форму редактирования из списка клиентов. Форма редактирования будет вызывать ее, и вы будете делать, что хотите, когда она будет вызвана.

  2. вызовите форму редактирования для события customerEdited, которое вы слушаете и на которое реагируете (без шины приложения)

  3. использовать шину событий всего приложения для централизованного управления событиями, как показано.

0 голосов
/ 17 августа 2011

Для получения естественного потока в любом коде MVP есть несколько важных идей:

  1. Это ведущий, который управляет видом, а не наоборот.
  2. Из-за 1. представление не должно знать о существовании ведущего. Меньше зависимостей обычно означает более легкое обслуживание.

В C # я нахожу события очень полезными для отделения докладчиков от представлений. Подробности в предыдущем ответе: Модель-Представление-Презентатор в WinForms

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...