Вопрос, вкратце:
В MVC, как вы различаете щелчок флажка (или изменение поля выбора или списка) от человеческого значения «Контроллер, измените модель», и щелчок флажка (или изменение окна выбора или изменения списка) от значения Контроллера «Я обновляю представление, потому что модель изменилась»?
Пример:
У меня есть приложение JS (все одна большая страница HTML + JS; за ним стоит сервер, и продолжается AJAX, но это не важно для примера), в котором есть понятие «Вершины», связанное «Краями». Пользовательский интерфейс позволяет добавлять и удалять вершины на карте, а также включать или отключать края между парами вершин.
Существует два способа отключить Edge от вершины A до вершины B:
- нажмите на Edge, чтобы в окне «Edge Details» появилась кнопка «Disable This Edge»; или
- нажмите на вершину A (или B), чтобы в окне «Детали вершины» появился контрольный список соседних вершин, из которого вы можете снять отметку с вершины B (или A).
Вот как это работает под капотом в MVC (, но смотрите обновление в конце этого поста, где я исправляю проблемы в моем понимании ):
- Модель: список объектов Vertex и список объектов Edge.
- Представление: пользовательский интерфейс GMaps с маркерами и полилиниями, а также флажками и кнопками, а также DIV «Vertex Details» и «Edge Details».
- Контроллер:
- JS-функции, которые обновляют модель при срабатывании событий на флажках и кнопках; и
- Функции JS, которые обновляют представление при возникновении событий в моделях.
Вот особая нелегкость :
- Пользователь имеет окно сведений о вершине, ориентированное на вершину A, и окно сведений о ребре, ориентированное на край от вершины A до вершины B.
- Пользователь нажимает «Отключить этот край» в окне «Сведения о ребре».
- Функция контроллера 1 получает событие click и вызывает disable () для объекта модели Edge.
- Объект модели Edge запускает событие «Я только что отключился».
- Функция контроллера 2 получает событие «Я только что отключился», и
- перерисовывает окно сведений о крае, говоря: «Я отключен!» и
- снимает отметку с вершины B в окне сведений о вершине.
- Дерьмо! Это снова запускает функцию контроллера 1, которая прослушивала события пользовательского интерфейса, которые означают, что фронт был отключен!
Таким образом, происходит ненужное повторное обновление модели и повторное обновление представления. В более сложном представлении с событиями, которые инициируют события, которые инициируют события, это может привести к десяткам посторонних обновлений!
Обновление: отличный ответ.
Я немного неправильно понял MVC. У меня нет только одного вида, как я описал выше: у меня есть несколько видов на несколько моделей. В частности, у меня есть флажок View of Edges для определенного узла и отдельный «подробный стиль окна» View of Edge.
Кроме того, у меня не должно быть одной функции контроллера, обновляющей все виды при изменении модели: каждый вид должен изменять сам при изменении модели.
Таким образом, если каждое представление регистрируется для событий «состояние обновлено» в модели, и каждое представление обновляется при получении этих событий, тогда ответ на мой круговой вопрос о событиях будет следующим:
Представление списка флажков отключит события флажков в тот момент, когда оно обновляет флажки после изменения состояния модели.
Теперь, если пользователь отключает Edge через окно Edge Detail, Контроллер обновляет Edge Model, просмотр списка флажков получает уведомление об обновлении, а просмотр списка флажков достаточно умен, чтобы отключить события флажков при изменении статус соответствующего флажка.
Это гораздо более приемлемо, чем мое первоначальное решение, когда один контроллер обновляет ВСЕ виды - и, следовательно, должен знать, какие виды нуждаются в особом уходе и использовании, чтобы избежать циклов. Вместо этого только один вид с проблемными элементами пользовательского интерфейса должен иметь дело с проблемой.
Спасибо тем, кто ответил на мой вопрос!