Динамічне зв'язування даних у HTML і JS

Всім доброго часу доби.

Якщо ви задаєтеся одним з таких запитань:

  • що таке динамічне пов'язування даних?
  • як працює зв'язування даних в 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

Дякую за увагу.