¿Deberíamos vincular la vista a una propiedad modelo o ViewModel debería tener la suya propia?

21

Estoy comenzando un proyecto con el siguiente entorno técnico: .Net 4.0, Entity Framework 4.0, WPF con arquitectura MVVM

Vi muchos ejemplos en la red, algunos libros con este entorno. En algunos de los ejemplos, los autores tuvieron esta idea:

  1. Viemodel tendrá una instancia de la clase Model (Entity Framework Entity eg Person)
  2. Enlace los controles de vista WPF a las propiedades del modelo

Mientras que algunos autores hicieron:

  1. Viemodel expondrá todas las propiedades del modelo.
  2. Enlace los controles de vista WPF a las propiedades de ViewModel en lugar de al modelo directamente.

Entonces, ¿es una buena idea dejar que la vista enlace propiedades del modelo en lugar de que viewmodel exponga las suyas propias? ¿O cuál es más preferido?

Pravin Patil
fuente
Personalmente, encuentro que exponer las propiedades del modelo para dar como resultado una buena separación de su capa de datos y capas lógicas.
Alex Hope O'Connor

Respuestas:

25

Creo que muchos programadores primero intentan tomar el atajo de vinculación directamente al modelo, pero en mi experiencia esto tiene algunos inconvenientes importantes. El problema principal es que si NHibernate o similar persiste en su modelo de entidad, tan pronto como la Vista actualice la propiedad del modelo, NHibernate podría persistir esos cambios en la base de datos. Eso no funciona bien para las pantallas de edición que tienen un botón Guardar / Cancelar. De hecho, puede elegir esperar y persistir todo como un lote, pero la idea es que cuando cambia el modelo, está confirmando su cambio.

Por lo tanto, aún podría evitar vincularse directamente a las propiedades del modelo en pantallas de solo lectura, pero luego tendrá una inconsistencia.

Además, la mayoría de los modelos no se implementan, INotifyPropertyChangedpor lo que pueden no ser objetivos de enlace adecuados si el estado de la pantalla cambia después de la visualización inicial.

Dada la facilidad de las propiedades automáticas, sugiero siempre vincular la vista al modelo de vista, no al modelo. Es consistente, simple y le brinda la mayor flexibilidad para admitir cambios en el futuro.

Scott Whitlock
fuente
Me gusta tu respuesta. +1 por mencionar Editar / Guardar pantalla ... Pero sería desalentador escribir las propiedades dos veces, una en el modelo y otra vez en el modelo de vista. También aumentaría el tiempo de desarrollo. ¿Crees que es justificable hacerlo ...?
Pravin Patil
99
@Pravin Patil - fwiw, cada vez que tomé ese atajo, me maldije más tarde cuando tenía que regresar y arreglarlo. Hay relativamente poco esfuerzo para volver a implementar las propiedades en ViewModel, especialmente si son de solo lectura (porque puede usar propiedades implementadas automáticamente con un setter privado). El hecho es que, en la mayoría de los casos, el modelo es una estructura de datos diferente que el modelo de vista. Deje la flexibilidad para cambiar el Modelo sin afectar la Vista. Cuanto menos tenga que cambiar la Vista, mejor, porque la Vista es difícil de probar.
Scott Whitlock
44
@Scott Whitlock: Llevo dos años desarrollando aplicaciones WPF con NHibernate y nunca tuve ningún problema relacionado directamente con el modelo. De hecho, cuando cambia una propiedad del modelo, se trata principalmente del mismo esfuerzo para el cambio, independientemente de lo que esté vinculado. Y cuando realmente necesito hacer algo de enrutamiento en ViewModel, más tarde, no valía la pena invertir el tiempo antes de necesitarlo. Sigo el enfoque de YAGNI (todavía) y no tengo dificultades. Creo que usted y los demás aquí están siendo un poco dogmáticos sobre este tema.
Falcon
16

El punto de a ViewModeles que es un modelo de View.

Debe vincular el ViewModela View, no a ninguna Modelpropiedad (no directamente, de todos modos).

Oded
fuente
8

Encuentro ambos métodos aceptables

La vinculación solo al ViewModel es el enfoque "MVVM-purist" y conduce a una mejor separación entre capas. La vinculación al modelo suele ser más rápida y más conveniente.

A menos que tenga una buena razón para separar completamente las capas (tamaño del proyecto, problemas de mantenimiento futuros, tipo de modelo con el que estoy trabajando, etc.), me uniré al modelo.

Rachel
fuente
7

Creo que lo que está viendo es un concepto llamado vincular, es decir, si su modelo tiene una propiedad llamada nombre y su modelo de vista expone esta propiedad sin edición o conversión adicional, entonces puede vincular el modelo para que así sea.

Pseudocódigo:

 {Binding: MyViewModel.MyModel.Name}

Esto se hace para reducir la cantidad de propiedades 'Fluff' en el modelo de vista, desafortunadamente también es una mala idea a largo plazo. El concepto de un modelo de vista es garantizar que la vista no dependa del modelo. Al vincular, debe asegurarse de que su modelo contenga una propiedad llamada nombre; de ​​lo contrario, su implementación se interrumpirá.

Sin embargo, si solo vincula hasta el modelo de vista, puede cambiar el modelo y la vista nunca se sabrá, ya que solo verá la propiedad llamada Nombre en el modelo de vista.

Ahora esto se puede mitigar en ciertas circunstancias en las que su modelo se basa en una interfaz. Entonces, si la interfaz tenía un IBaseDetails que expuso la propiedad ModuleName, entonces podría:

Pseudocódigo:

 {Binding: MyViewModel.MyModel.ModuleName}

Siempre y cuando cualquiera de los Modelos que realice satisfaga la interfaz IBaseDetails, su dorado, tenga en cuenta, sin embargo, que este es un caso límite y, en general, siempre es un 90% mejor para envolver su modelo de vista alrededor de los modelos que cubre.

DeanMc
fuente
2

Si está viendo mucha fricción al intentar ir desde Modelo -> ViewModel, intente algo como AutoMapper. Elimina el tedio asociado con las propiedades de copia manualmente.

Bryan Boettcher
fuente
1

Llegué aquí solo porque tenía la misma duda y me convencí de que siempre me uniría para ver el modelo en lugar del modelo.

Tome el enfoque de la forma reactiva angular. Usted crea un grupo de formularios utilizando cierta información del Modelo de vista, pero luego tiene que acceder al formulario. Los valores para obtener los valores y copiar los valores en el modelo usando cualquier mapeador automático o manual, creo que no hay nada más bello que enlazar propiedades en el modelo de vista, por ejemplo, tengo una página de vista de proyecto donde tengo el nombre del proyecto, nombre del cliente, etc.

Existe una relación entre proyecto y cliente ya que un proyecto tiene un cliente. Entonces, a este nivel, no debería importarme esa relación, solo necesito mostrar visualmente el nombre del proyecto y el nombre del cliente en la vista, así que pongo 2 propiedades en el nombre del proyecto del modelo de vista y el nombre del cliente, así que enlazo los controles de vista a ambos ellos, luego me preocuparé por dar valores a esas propiedades en el código detrás de tomar de cualquier estructura que tenga el modelo.

Lo mismo podría ser para actualizar el modelo en el caso de guardar / cancelar no hay nada más limpio.

Ivan Carmenates García
fuente
esta publicación es bastante difícil de leer (muro de texto). ¿Te importaría editarlo en una mejor forma?
mosquito
Ahí tienes, salud.
Ivan Carmenates García