Всем доброго времени суток.
Если вы задаетесь одним из следующих вопросов:
  • что такое динамическое связывание данных?
  • как работает связывание данных в AngularJS или ему подобных MVVM-фреймворках?
  • чем, черт возьми, MPV отличается от MVVM?

Тогда вам под кат…
И да… в конце, как всегда, ссылка на код ;)

Про MVP:
MVP (Model-View-Presenter) — это один из самых распространенных шаблонов проектирования UI.

Суть его заключается в следующем:
  • Presenter подписывается на события от View
  • View эмитит события
  • Presenter ловит события и делает запросы в Model
  • При получении ответа от Model, Presenter обновляет View

Сразу же в глаза бросается ключевое отличие MVP от MVC: MVP, в отличии от MVC, имеет двустороннюю связь с View.
Запомним и пойдем дальше…

Про MVVM:
MVVM (Model-View-ViewModel) — это улучшеная форма MVP, при чем грань между ними так тонка, что иногда думаешь: «О, небо! За что ты так со мной?»

Сейчас объясню что я имею ввиду.

Суть MVVM заключается в следующем:
  • ModelView подписывается на события от View
  • View эмитит события
  • ModelView ловит события и делает запросы в Model
  • При получении ответа от Model, ModelView обновляет View




Если отбросить формальности, то так оно и есть. Поэтому я и сказал, что грань между MVP и MVVM очень тонка.

Глобально, разница лишь в том, что MVVM реализует более гибкий слушатель событий от View.
При чем реализует таким образом, что становится доступным так называемое декларативное динамическое связывание данных.

Про динамическое связывание данных:
Это такой механизм, при котором, изменив значение модели с любой стороны(со стороны View или Model), это изменение моментально вступит в силу. То есть, изменив значение в Model (в MVVM — ViewModel частично берет на себя функцию модели), оно сразу отобразится во View и наоборот.

Вы можете спросить: «Если в MVP есть двусторонняя связь между View и Presenter, то почему мы не можем реализовать динамическое связывание данных на MVP?».

Ответ очень прост — можем!
По сути, MVP уже подразумевает динамическое связывание данных в той или иной степени.
И, если MVP это чисто императивный подход к связыванию данных, то MVVM — декларативный.

Вот и вся разница.
Но суть у них одна и та же!

Про реализацию:
Теперь рассмотрим вопросы, связанные с реализаций динамического связывания данных.
Начнем с того, что, на текущий момент, браузер не способен динамически отслеживать изменение значений в переменных.
Конечно, есть такая штука как Object.observe(), но эта вещь, пока еще, не является частью стандарта.
Поэтому исходим из того, что
браузер не способен динамически отслеживать изменение значений в переменных

Соответсвенно, необходимо как-то понимать: когда нужно произвести синхронизацию между Model и View.
В современных фреймворках, типа Angular или Knockout, к этому вопросу подходят очень просто: вешают слушатели на разные события от элемента, которому необходимо динамическое связывание данных.
Например, для text input вешается слушатель на событие keyup.
Для button — click
И т.д.

Внутри обработчика происходит чтение новых данных и затем запускается механизм синхронизации оных с Model.

Вот, собственно, и вся история.

Кстати, если вы используете Angular, то, скорее всего, вам очень часто приходится прибегать к использованию таких вещей, как сервис $timeout…
Если вы используете $timeout на автоматизме, потому что так написано где-то на stack overflow, но не понимаете его сути, то знайте, что $timeout ждет, пока закончится текущий $digest-цикл, затем выполняет код, который вы ему передали, и затем снова запускает $digest-цикл. Именно так и достигается обновление данных, если оно было инициировано не из внутренностей Angular.

Что такое $digest-цикл?
В AngularJS это как раз и есть процесс синхронизации значений между Model и View.

И, как обещал, ссылка на Gist, в котором реализовано простейшее динамическое связывание данных.

В нескольких словах:
  • выбираем все элементы, у которых есть атрибут data-bind
  • регистрируем эти элементы как слушатели изменений модели
  • вешаем на document общий обработчик, который будет производить синхронизацию между View и Model


Спасибо за внимание.

Комментарии (28)


  1. Aux
    19.02.2016 02:24

    MVP, MVVM… Еще несколько лет назад это называлось MVC with data bindings!