Evento Bubbling y MVP: ASP.NET

Estoy tratando de aprender MVP

Está utilizando formularios web en ASP.NET. Tengo dos controles de usuario CurrentTimeView.ascx y MonthViewControl.ascx. CurrentTimeView muestra el tiempo. Hay un cuadro de texto para agregar días en el mismo control. La fecha recién obtenida se llama “fecha resultante”. Cuando se hace clic en el botón para agregar días, se genera un evento “myBtnAddDaysClickedEvent”.

En MonthViewControl, hay una etiqueta que muestra el mes de la “fecha resultante”. Actualmente estoy estableciendo un valor de muestra para la variable “monthValueToPass” (ya que no sé cómo hacerlo correctamente). ¿Cómo configuro el valor de la variable monthValueToPass para que cumpla con el modelo MVP?

string monthValueToPass = "TEST"; monthPresenter.SetMonth(monthValueToPass); 

La expectativa es crear un MVP que sea fácil de realizar en Unit Testing y que no viole a MVP architecure.

Nota: Aunque este es un ejemplo simple, espero una respuesta escalablt a la unión de datos en el control GridView utilizando MVP y mecanismos de validación.

Nota: ¿Puede la vista ser totalmente independiente del presentador?

Nota: cada control de usuario es vistas separadas aquí

Nota: ¿Puede haber varias vistas para el mismo presentador (como diferentes controles para varios usuarios según su permiso?)

DIRECTRICES

  1. Model View Presenter – Pautas

– CÓDIGO COMPLETO–

 using System; public interface ICurrentTimeView { //Property of View DateTime CurrentTime { set; } //Method of View void AttachPresenter(CurrentTimePresenter presenter); 

}

 using System; public interface IMonthView { //Property of View string MonthName { set; } //Method of View //View interface knows the presenter void AttachPresenter(MonthPresenter presenter); 

}

  using System; public class CurrentTimePresenter { private ICurrentTimeView view; //Constructor for prsenter public CurrentTimePresenter(ICurrentTimeView inputView) { if (inputView == null) { throw new ArgumentNullException("view may not be null"); } this.view = inputView; } //Method defined in Presenter public void SetCurrentTime(bool isPostBack) { if (!isPostBack) { view.CurrentTime = DateTime.Now; } } //Method defined in Presenter public void AddDays(string daysUnparsed, bool isPageValid) { if (isPageValid) { view.CurrentTime = DateTime.Now.AddDays(double.Parse(daysUnparsed)); } } 

}

 using System; public class MonthPresenter { private IMonthView monthView; //Constructor for prsenter public MonthPresenter(IMonthView inputView) { if (inputView == null) { throw new ArgumentNullException("view may not be null"); } this.monthView = inputView; } //Method defined in Presenter //How does presenter decides the required value. public void SetMonth(string monthValueInput) { if (!String.IsNullOrEmpty(monthValueInput)) { monthView.MonthName = monthValueInput; } else { } } 

}

Control de usuario 1

  

 using System; using System.Web.UI; public partial class Views_CurrentTimeView : UserControl, ICurrentTimeView { //1. User control has no method other than view defined method for attaching presenter //2. Properties has only set method private CurrentTimePresenter presenter; // Delegate public delegate void OnAddDaysClickedDelegate(string strValue); // Event public event OnAddDaysClickedDelegate myBtnAddDaysClickedEvent; //Provision for getting the presenter in User Control from aspx page. public void AttachPresenter(CurrentTimePresenter presenter) { if (presenter == null) { throw new ArgumentNullException("presenter may not be null"); } this.presenter = presenter; } //Implement View's Property public DateTime CurrentTime { set { //During set of the property, set the control's value lblCurrentTime.Text = value.ToString(); } } //Event Handler in User Control protected void btnAddDays_OnClick(object sender, EventArgs e) { if (presenter == null) { throw new FieldAccessException("presenter null"); } //Ask presenter to do its functionality presenter.AddDays(txtNumberOfDays.Text, Page.IsValid); //Raise event if (myBtnAddDaysClickedEvent != null) { myBtnAddDaysClickedEvent(string.Empty); } } 

}

Control de usuario 2

  

 using System; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class Views_MonthViewControl : System.Web.UI.UserControl, IMonthView { //1. User control has no method other than view defined method for attaching presenter //2. Properties has only set method private MonthPresenter presenter; //Provision for gettng the presenter in User Control from aspx page. public void AttachPresenter(MonthPresenter presenter) { if (presenter == null) { throw new ArgumentNullException("presenter may not be null"); } this.presenter = presenter; } //Implement View's Property public string MonthName { set { //During set of the popert, set the control's value lblMonth.Text = value.ToString(); } } protected void Page_Load(object sender, EventArgs e) { } 

}

Página ASPX

    

TÍTULO DE LA PÁGINA

   

 using System; using System.Web.UI; public partial class ShowTime : Page { CurrentTimePresenter currentTimePresenter; MonthPresenter monthPresenter; protected void Page_Load(object sender, EventArgs e) { HelperInitCurrentTimeView(); HelperInitMonth(); } private void HelperInitMonth() { //Create presenter monthPresenter = new MonthPresenter(ucCtrlMonthView); //Pass the presenter object to user control ucCtrlMonthView.AttachPresenter(monthPresenter); } private void HelperInitCurrentTimeView() { //Cretes presenter by passing view(user control) to presenter. //User control has implemented IView currentTimePresenter = new CurrentTimePresenter(ucCtrlcurrentTimeView); //Pass the presenter object to user control ucCtrlcurrentTimeView.AttachPresenter(currentTimePresenter); //Call the presenter action to load time in user control. currentTimePresenter.SetCurrentTime(Page.IsPostBack); //Event described in User Control ???? Subsribe for it. ucCtrlcurrentTimeView.myBtnAddDaysClickedEvent += new Views_CurrentTimeView.OnAddDaysClickedDelegate(CurrentTimeViewControl_AddButtonClicked_MainPageHandler); } void CurrentTimeViewControl_AddButtonClicked_MainPageHandler(string strValue) { string monthValue = "l"; monthPresenter.SetMonth("SAMPLE VALUE"); //myGridCntrl.CurentCharacter = theLetterCtrl.SelectedLetter; //myGridCntrl.LoadGridValues(); } 

}

Algunas discusiones de MVP:

Model View Presenter – Pautas

En MVP donde escribir validaciones

MVP: ¿Deben las vistas poder llamar directamente a los métodos del presentador o deben siempre generar eventos?

Eventos o propiedad de MVP

El modelo en MVP – Eventos

MVP: ¿Debería el presentador usar Session?

¿Por qué los presentadores se conectan a los eventos de visualización en lugar de ver los métodos de presentación de presentador en la mayoría de las implementaciones de ASP.NET MVP?

Métodos públicos o suscribirse a Ver eventos

Patrón de MVP, ¿Cuántas vistas tiene un presentador?

MVP y UserControls e invocación

Formularios web ASP.NET: controles de controles de usuario y modelo de vista modelo

Restringir la violación de la architecture – asp.net MVP

Modificación de control en la capa de presentación

Desacoplamiento de la vista, presentación y formularios web de ASP.NET Web Forms

TLDR el código.

Así es como lo haría. Usted dice que hay 2 controles en la misma página. Para que pueda ser servido por un ContainerVM con referencias (miembros) de TimeVM y MonthVM.

  1. TimeVM actualiza una propiedad de respaldo ResultantDate cada vez que hace lo suyo.
  2. ContainerVM se ha suscrito a las notificaciones de cambio de propiedad para TimeVM.ResultantDate. Cada vez que recibe una notificación de cambio, llama a MonthVM.SetMonth ()

Esto ahora se puede probar sin usar ninguna vista, solo en el nivel del presentador.

Gracias por los aportes. Remití MVP Quickstarts http://msdn.microsoft.com/en-us/library/ff650240.aspx . Model can raise events . Creo que debería ir con ese enfoque. Cualquier pensamiento es bienvenido

Además, he publicado http://forums.asp.net/t/1760921.aspx/1?Model+View+Presenter+Guidelines para recostackr reglas generales sobre MVP.

Citar

Desarrolle Presentador que se pueda comunicar tanto con Vista como con Modelo. El presentador solo puede tener conocimiento de las interfaces de visualización. Incluso si la vista concreta cambia, no afecta al presentador.

En la vista concreta, los controladores de eventos del control simplemente llamarán a los métodos del presentador o plantearán eventos a los que el presentador se habría suscrito. No debe haber una regla / lógica de presentación escrita en vista concreta.

El presentador debe tener solo la interfaz objeto de modelo; no es un modelo concreto Esto es por la facilidad de las Pruebas unitarias

La vista puede referir entidades comerciales. Sin embargo, no debería haber ninguna lógica escrita asociada con los objetos de la entidad. Puede simplemente pasar el objeto de la entidad al presentador.

La interfaz de visualización debe ser una abstracción. NO debe tener ningún control ni referencia de System.Web. En vista concreta, no debería haber otro método que los métodos definidos por la interfaz.

El “Modelo” nunca sabe acerca de la vista concreta, así como la vista de interfaz

“Modelo” puede definir y generar eventos. El presentador puede suscribir estos eventos planteados por modelo.

Los métodos públicos en el presentador deben ser sin parámetros. El objeto de vista debe acceder solo a métodos sin parámetros del presentador. Otra opción es ver definir eventos a los que el presentador puede suscribirse. De cualquier manera, no debería haber ningún parámetro que pase.

Como el modelo tiene todos los valores necesarios (para ser almacenados en la base de datos), no es necesario pasar ningún valor al modelo de la vista (la mayoría de las veces). Por ejemplo, cuando se selecciona un elemento en la lista desplegable, solo se debe pasar el índice actual de los controles al modelo. Entonces el modelo sabe cómo obtener los valores de dominio correspondientes. En este caso, la vista no necesita pasar nada al presentador. El presentador sabe cómo obtener valor de la vista.

La vista puede hacer uso del modelo directamente (sin usar el presentador). Por ejemplo, SelectMethod de ObjectDataSource. Pero el controlador nunca sabe acerca de la vista concreta, así como la vista de interfaz.

El presentador hace referencia a la interfaz de vista en lugar de la implementación concreta de la vista. Esto le permite reemplazar la vista real con una vista simulada cuando se ejecutan pruebas unitarias.

No tengo experiencia con ASP.net, pero creo que sigo la esencia de lo que estás tratando de hacer.

Parece que bajará al nivel de su presentador al hacer presentadores para los elementos individuales de la interfaz de usuario. En este caso, el mes y el tiempo. Lo pensaría más como el período ShowTime. ShowTime tiene la capacidad de mostrar el mes y la hora.

Para usar esto con MVP. Entonces necesitarás un IShowTimeView que la página implementará. (No los controles). Y luego escriba ShowTimePresenter que usa IShowTimeView para enviar y recuperar valores.

Tendrá ShowTime implementará la interfaz IShowTimeView. Encaminará elementos como la hora, los eventos AddDay y el mes hacia y desde los controles reales en la página.

Entonces, si entiendo tu reseña. La secuencia del evento sería algo como esto.

El usuario escribe en los días para agregar. El usuario hace clic en Agregar días. Agregar días activa el evento que llama a un método en el Presente para agregar días. El método en el presentador que agrega días hará su cálculo y otros pasos necesarios. El método agregar días utilizará el puntero Ver en el presentador para indicarle a la vista que actualice el mes con el valor calculado. La Vista tomará entonces el valor calculado estableciendo la propiedad correcta en el control.

Para realizar pruebas unitarias, debe crear un objeto simulado que implemente IShowTimeView y usarlo en lugar del objeto de página real.