Я познакомился с MVVM и считаю, что понимаю концепции, лежащие в его основе. Тем не менее, кое-что, что мне еще предстоит увидеть, хорошо документировано - это «Модель» в MVVM. Кажется, постоянно возникает следующая ситуация, и я не нашел удовлетворительного способа справиться с ней:
Модели (упрощенное):
class School{
public List<Classroom> Classrooms{get;set;}
}
class Classroom{
public List<Student> Students{get;set;}
}
class Student{
public string Name {get;set;}
}
Модели представления (упрощенное):
class SchoolViewModel : BaseViewModel
{
School School;
ObservableCollection<ClassroomViewModel>ClassroomListItemViewModels{get;set;}
ClassroomDetailViewModel ClassroomDetailViewModel{get;set;}
}
class ClassroomDetailViewModel: BaseViewModel
{
Classroom Classroom;
int NumberOfStudents {get; set}
ObservableCollection<Student> StudentListItemViewModel{get;set;}
StudentDetailViewModel StudentDetailViewModel{get;set;}
}
ClassroomListItemViewModel:BaseViewModel{
Classroom Classroom;
int NumberOfStudents {get; set}
}
class StudentListItemViewModel: BaseViewModel
{
Student Student;
string Name{get; set}
}
class StudentDetailViewModel: BaseViewModel
{
Student Student;
string Name{get; set}
}
(опуская INotifyPropertyChanged для простоты ..)
Просмотры: https://imgur.com/a/C4HmLU5
SchoolView показывает список классов, подробный вид выбранной классной комнаты. ,Подробное представление классной комнаты показывает список представлений учащихся, а также подробное представление выбранного учащегося
Желаемое поведение: изменения в модели должны распространяться на все представления / модели представления, показывающие эту модель.
MyПодходы:
1) Добавить INotifyPropertyChanged или что-то похожее на модель -> Это загрязняет мою модель
2) Добавить метод Update () для каждой модели представления, который перестраивает его из модели. -> Требуется, чтобы кто-то следил за изменением модели, а также знает, на какие видовые модели влияет это изменение
3) Добавьте событие ModelChanged в некоторый глобальный контекст, на который могут подписаться Viewmodels, а также попросите повыситьсобытие. -> При удалении ListItemViewModel нужно не забывать отписывать его от контекста, чтобы предотвратить утечку памяти
Требуемое поведение:
Изменения в Viewmodel должны быть сохранены в модели в какой-то момент
Мои подходы:
1) У ViewModel есть метод StoreToModel (), который применяет изменения к модели -> как уведомить все другие модели представления, которые зависят от этой модели, о том, что что-то изменилось
2) НекоторыеОбщий контекст решает, когда сохранять изменения данных -> много логики в «вершине» иерархии, поскольку он должен контролировать все
По сути, все это сводится к двум топологиям, пирамидальной и звездообразной. Пирамида толкает изменения вниз через иерархию моделей представления, в то время как форма звезды состоит из некоторого глобального контекста, в который все модели представления могут публиковать и подписывать свои изменения
Лично я предпочитаю глобальный контекст, поскольку он позволяет мне гибко добавлять модели представлениядо тех пор, пока они содержат экземпляр этого контекста.
//Point of intersection between many viewmodels
class ModelContext
{
public void ModelChanged(object model){
ModelChangedEvent.Invoke(model);
}
public event ModelChangedEventHandler ModelChangedEvent;
}
Один недостаток, который я обнаружил, заключается в том, что я должен позаботиться о том, чтобы избежать утечек памяти (например, когда я удаляю ViewModel из коллекции, я должентакже не забудьте отписаться от него)
Есть ли какой-то шаблон, который я пропустил, который просто делает каждую работу? Как насчет моего глобального ModelContext? С этим что-то не так?