Necesito ayuda para crear modelos de vista para el siguiente escenario:
- Datos jerárquicos profundos
- Múltiples vistas para el mismo conjunto de datos.
- Cada vista es una vista única, que cambia dinámicamente, basada en la selección activa
- Dependiendo del valor de una propiedad, muestre diferentes tipos de pestañas en un control de pestañas
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
Figura 2: Sala activa diferente. Múltiples vistas actualizadas. Los elementos de control de pestaña cambiaron según la propiedad del objeto.
Figura 3: Diferentes tipos de selección. Cambios de vista completa
Respuestas:
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
O un modelo de vista para cada vista
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:
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í:
fuente
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.
fuente