Ayuda con MVVM complejo (vistas múltiples)

18

Necesito ayuda para crear modelos de vista para el siguiente escenario:

  1. Datos jerárquicos profundos
  2. Múltiples vistas para el mismo conjunto de datos.
  3. Cada vista es una vista única, que cambia dinámicamente, basada en la selección activa
  4. Dependiendo del valor de una propiedad, muestre diferentes tipos de pestañas en un control de pestañas

ingrese la descripción de la imagen aquí

Mis preguntas:

¿Debo crear una representación de modelo de vista para cada vista (VM1, VM2, etc.)?

1. Yes:
    a. Should I model the entire hierarchical relationship? (ie, SubVM1, HouseVM1, RoomVM1)
    b. How do I keep all hierarchies in sync? (e.g, adding/removing nodes)

2. No:
    a. Do I use a huge, single view model that caters for all views?

Aquí hay un ejemplo de una vista única

Figura 1: Múltiples vistas actualizadas en función de la sala activa. Control de pestaña de aviso

ingrese la descripción de la imagen aquí

Figura 2: Sala activa diferente. Múltiples vistas actualizadas. Los elementos de control de pestaña cambiaron según la propiedad del objeto.

ingrese la descripción de la imagen aquí

Figura 3: Diferentes tipos de selección. Cambios de vista completa

ingrese la descripción de la imagen aquí

jayars
fuente
por cierto, ¿qué es una vista muli? ¿error de tipografía?
JensG
"Muli view" fue un error tipográfico. Me refería a diferentes vistas para el mismo modelo / modelo de vista. Mi pregunta fue, ¿debería remodelar / ajustar toda la jerarquía del modelo para cada vista, de modo que cada modelo de vista solo contenga lo que necesita la vista individual? ¿O debería crear una jerarquía de modelo de vista única que contenga propiedades de todas las vistas? Desde que publiqué esta pregunta, tuve la (des) suerte de descubrir las ventajas y desventajas de los dos, de la manera más difícil. Actualizaré este hilo en el futuro con un diagnóstico completo de mi experiencia, una vez que las cosas no estén tan agitadas.
jayars
Recuerde que una regla de diseño es mostrar las cosas generales primero y luego profundizar en los detalles. te dejará con una vista clara y si el usuario profundiza, aparecerán nuevas vistas. así que use pequeñas vistas con su modelo de vista aparte. consulte la interfaz de usuario de diseño de
Csharls
@jsjslim Me estremecí cuando leí "mantener todas las jerarquías sincronizadas". Sospecho que te fuiste con la vista múltiple, y sospecho que te arrepientes (pero me he equivocado antes). Por el bien de otros lectores que puedan tener la misma pregunta, ¿puede al menos darnos una respuesta rápida (ish)?
Guy Schalnat
2
@ guy-schalnat La vista múltiple era un requisito. Mi problema era tratar de descubrir cómo construir los modelos de vista. El proyecto aún está en curso y no puedo encontrar el tiempo para escribir un análisis completo. Pero en resumen: debería haber ignorado la estructura del modelo y centrado en las vistas. La complejidad que encontré fue autoimpuesta: quería usar el enlace de datos de WPF tanto que me obsesioné. Lo que hice al final fue bueno, viejo "copiar / pegar / refactorizar". El diseño final que surgió fue ligero (poca repetición) y, lo que es más importante, funcionó. Escribiré un análisis completo en el futuro.
jayars

Respuestas:

13

Para responder a la pregunta, Sí, cada vista debe tener su propio Modelo de vista. Pero no hay necesidad de modelar toda la jerarquía. Solo lo que la vista necesita.

El problema que tuve con la mayoría de los recursos en línea con respecto a MVVM:

En la mayoría de los ejemplos, la Vista es un mapeo casi 1 a 1 del Modelo. Pero en mi escenario, donde hay diferentes puntos de vista para diferentes facetas del mismo Modelo, me encuentro atrapado entre dos opciones:

Un modelo de vista monolítica que utilizan todos los demás modelos de vista

ingrese la descripción de la imagen aquí

O un modelo de vista para cada vista

ingrese la descripción de la imagen aquí

Pero ambos no son ideales.

El modelo de vista orientado al modelo (MVM), aunque bajo en duplicación de código, es una pesadilla para mantener

El modelo de vista orientado a la vista (VVM) produce clases altamente especializadas para cada vista, pero contiene duplicados.

Al final, decidí que tener una VM por vista es más fácil de mantener y codificar, así que seguí con el enfoque VVM.

Una vez que el código funciona, comencé a refactorizar todas las propiedades y operaciones comunes en su forma actual y final:

ingrese la descripción de la imagen aquí

En esta forma final, la clase de modelo de vista común se compone en cada VVM.

Por supuesto, todavía tengo que decidir qué se considera común / especializado. Y cuando se agrega / fusiona / elimina una vista, este equilibrio cambia.

Pero lo bueno de esto es que ahora soy capaz de empujar miembros hacia arriba / abajo de común a VVM y viceversa fácilmente.

Y una nota rápida sobre cómo mantener los objetos sincronizados:

Tener un modelo de vista común se encarga de la mayor parte de esto. Cada VVM puede simplemente tener una referencia al mismo modelo de vista común.

También tiendo a comenzar con métodos simples de devolución de llamada y evolucionar a evento / observador si surge la necesidad de múltiples oyentes.

Y para eventos realmente complejos (es decir, actualizaciones inesperadas en cascada), cambiaría a usar un Mediador.

No evito el código donde un niño tiene una referencia a su padre. Cualquier cosa para que el código funcione.

Y si surge la oportunidad de refactorizar, la aprovecharía.

Las lecciones que aprendí:

  1. Código feo / de trabajo> Código hermoso / no funciona
  2. Es más fácil fusionar múltiples clases pequeñas, que dividir una clase enorme
jayars
fuente
Desearía poder votar esto dos veces. Esta es una de las explicaciones más claras de las opciones que he visto.
Humano inteligente
3

Mirando sus maquetas, definitivamente recomendaría crear una jerarquía de ViewModels y muchas vistas pequeñas. Y lo más probable es que tenga que modelar un poco de la jerarquía original.

Para mantener las cosas sincronizadas entre ViewModels, use eventos o tenga propiedades entre ellos entre ViewModels. La sincronización entre vistas y modelos de vista debe ser una propiedad de notificación estándar.

Eufórico
fuente