Preciso de ajuda para criar modelos de exibição para o seguinte cenário:
- Dados hierárquicos profundos
- Várias visualizações para o mesmo conjunto de dados
- Cada visualização é uma visualização única, de mudança dinâmica, com base na seleção ativa
- Dependendo do valor de uma propriedade, exiba diferentes tipos de guias em um controle de guia
Minhas perguntas:
Devo criar uma representação do modelo de exibição para cada exibição (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?
Aqui está um exemplo de uma única visualização
Figura 1: Várias visualizações atualizadas com base na sala ativa. Controle da guia Aviso
Figura 2: Sala ativa diferente. Várias visualizações atualizadas. Os itens de controle da guia foram alterados com base na propriedade do objeto.
Figura 3: Tipo de seleção diferente. Alterações na visualização inteira
Respostas:
Para responder à pergunta, Sim, cada visualização deve ter seu próprio modelo de visualização. Mas não há necessidade de modelar toda a hierarquia. Somente o que a vista precisa.
O problema que tive com a maioria dos recursos online relacionados ao MVVM:
Na maioria dos exemplos, a Visualização é quase um mapeamento 1 para 1 do Modelo. Mas, no meu cenário, onde existem diferentes visões para diferentes facetas do mesmo modelo, eu me vejo preso entre duas opções:
Um modelo de vista monolítico usado por todos os outros modelos de vista
Ou um modelo de vista para cada vista
Mas ambos não são ideais.
O MVM (Model-oriented View Model), embora com pouca duplicação de código, é um pesadelo para manter
O Modelo de Visão Orientada à Visão (VVM) produz classes altamente especializadas para cada visão, mas contém duplicatas.
No final, eu decidi que ter uma VM por exibição é mais fácil de manter e codificar, então fui com a abordagem VVM.
Depois que o código está funcionando, comecei a refatorar todas as propriedades e operações comuns em sua forma final atual:
Nesta forma final, a classe de modelo de vista comum é composta em cada VVM.
Claro, ainda tenho que decidir o que é considerado comum / especializado. E quando uma visualização é adicionada / mesclada / excluída, esse saldo é alterado.
Mas o bom disso é que agora eu sou capaz de enviar membros para cima / baixo do comum para o VVM e vice-versa facilmente.
E uma observação rápida sobre como manter os objetos sincronizados:
Ter um modelo de visão comum cuida da maior parte disso. Cada VVM pode simplesmente ter uma referência ao mesmo modelo de visualização comum.
Também costumo começar com métodos simples de retorno de chamada e evoluir para evento / observador, se houver necessidade de vários ouvintes.
E para eventos realmente complexos (ou seja, atualizações em cascata inesperadas), eu passaria a usar um Mediador.
Não evito o código em que uma criança tem uma referência anterior ao pai. Qualquer coisa para obter o código funcionando.
E se surgir a oportunidade de refatorar, eu aceitaria.
As lições que aprendi:
fonte
Analisando suas maquetes, eu recomendaria definitivamente a criação de hierarquia de ViewModels e muitas pequenas Views. E você provavelmente terá que modelar um pouco da hierarquia original.
Para manter as coisas sincronizadas entre os ViewModels, use eventos ou tenha propriedades entre si entre os ViewModels. A sincronização entre modos de exibição e modelos de exibição deve ser propriedades de notificação padrão.
fonte