Відповіді:
Двостороння прив'язка просто означає, що:
Магістральна система не має "вбудованої" реалізації №2 (хоча ви, звичайно, можете це зробити, використовуючи слухачів подій). Інші рамки, такі як Knockout, здійснюють автоматичне підключення двостороннього зв’язку .
У системі Backbone ви можете легко досягти №1, прив’язавши метод "візуалізації" представлення до події "зміни" своєї моделі. Щоб досягти №2, вам також потрібно додати вхідний елемент до слухача змін і зателефонувати model.set
в обробник.
Ось Загадка з двостороннім прив'язкою, встановленою в Backbone.
Двостороння прив'язка означає, що будь-які зміни, пов’язані з даними, що впливають на модель, негайно поширюються на відповідний вид (и) і що будь-які зміни, внесені в представлення (и) (скажімо, користувачем), негайно відображаються в базовій моделі . Коли дані програми змінюються, змінюється і інтерфейс користувача, і навпаки.
Це дуже солідна концепція побудови веб-додатку поверх, оскільки це робить абстракцію «Модель» безпечним, атомним джерелом даних, яке можна використовувати скрізь у програмі. Скажіть, якщо модель, прив’язана до подання, змінюється, то її відповідна частина інтерфейсу (перегляду) відображатиме це, незважаючи ні на що . І відповідна частина інтерфейсу користувача (подання) може бути безпечно використана як засіб збору входів / даних користувачів, щоб підтримувати актуальні дані програми.
Хороша двостороння обов'язкова реалізація, очевидно, повинна зробити цей зв'язок між моделлю та деякими переглядами якомога простішим з точки зору розробника.
Тоді зовсім неправдиво сказати, що Backbone не підтримує двостороннє прив'язування: хоча це не є основною особливістю фреймворку, його можна виконати досить просто, використовуючи події Backbone's. Це коштує кілька явних рядків коду для простих випадків; і може стати досить небезпечним для складніших прив’язок. Ось простий випадок (неперевірений код, написаний на льоту просто заради ілюстрації):
Model = Backbone.Model.extend
defaults:
data: ''
View = Backbone.View.extend
template: _.template("Edit the data: <input type='text' value='<%= data %>' />")
events:
# Listen for user inputs, and edit the model.
'change input': @setData
initialize: (options) ->
# Listen for model's edition, and trigger UI update
@listenTo @model, 'change:data', @render
render: ->
@$el.html @template(@model.attributes)
@
setData: (e) =>
e.preventDefault()
@model.set 'data', $(e.currentTarget).value()
model: new Model()
view = new View {el: $('.someEl'), model: model}
Це досить типовий зразок у сирому додатку "Хребна". Як видно, для цього потрібна пристойна кількість (досить стандартного) коду.
AngularJS та деякі інші альтернативи ( Ember , Knockout …) забезпечують двостороннє прив'язування як особливість першого громадянина. Вони абстрагують багато кращих справ у деяких DSL і роблять все можливе, інтегруючи двосторонній зв'язок у свою екосистему. Наш приклад виглядав би приблизно так із AngularJS (неперевірений код, див. Вище):
<div ng-app="app" ng-controller="MainCtrl">
Edit the data:
<input name="mymodel.data" ng-model="mymodel.data">
</div>
angular.module('app', [])
.controller 'MainCtrl', ($scope) ->
$scope.mymodel = {data: ''}
Досить короткий!
Але слід пам'ятати , що деякі Повноцінна двостороння розширення зв'язування дійсно існують для Backbone , а також (в сирому, суб'єктивному порядку убування складності): епоксидна , StickIt , ModelBinder ...
Наприклад, одна з прихильних функцій Epoxy - це те, що вона дозволяє оголошувати свої прив'язки (атрибути моделі <-> перегляд елемента DOM) або в межах шаблону (DOM), або в межах реалізації перегляду (JavaScript). Деякі люди сильно не люблять додавати "директиви" до DOM / шаблону (наприклад, атрибути ng- *, необхідні AngularJS, або атрибути прив'язки даних Ember).
Взявши за приклад Epoxy, можна переробити необроблений додаток Backbone у щось подібне (…):
Model = Backbone.Model.extend
defaults:
data: ''
View = Backbone.Epoxy.View.extend
template: _.template("Edit the data: <input type='text' />")
# or, using the inline form: <input type='text' data-bind='value:data' />
bindings:
'input': 'value:data'
render: ->
@$el.html @template(@model.attributes)
@
model: new Model()
view = new View {el: $('.someEl'), model: model}
Загалом, майже всі рамки JS "mainstream" підтримують двостороння прив'язка. Деякі з них, як-от Backbone, вимагають додаткової роботи, щоб зробити це безперебійним , але ті ж, що не застосовують певного способу зробити це, для початку. Тож мова йде справді про ваш душевний стан.
Також вас може зацікавити Flux , інша архітектура веб-додатків, що рекламують одностороннє прив'язування за допомогою кругового шаблону. Він заснований на концепції швидкого цілісного відтворення компонентів інтерфейсу користувача при будь-якій зміні даних для забезпечення згуртованості та полегшення міркування про код / потік даних. У тій же тенденції, ви можете перевірити концепцію MVI (Model-View-Intent), наприклад, Cycle .
У McGarnagle є чудова відповідь, і ви хочете прийняти його, але я подумав, що я згадаю (оскільки ви запитали), як працює прив'язка даних.
Він, як правило, реалізується шляхом запуску подій кожного разу, коли вноситься зміна даних, що призводить до оновлення слухачів (наприклад, інтерфейсу користувача).
Двостороння прив'язка працює, виконуючи це двічі, дотримуючись певної обережності, щоб ви не зациклювалися на циклі подій (де оновлення з події спричиняє звільнення іншої події).
Я збирався викласти це в коментарі, але це стало досить довго ...
Насправді emberjs
підтримує двостороннє прив'язування, що є однією з найпотужніших функцій рамки java MVC. Ви можете перевірити, де це згадується, binding
у своєму посібнику користувача.
для emberjs створити двостороння прив'язка - це створити нове властивість із рядком Binding в кінці, а потім вказати шлях із глобальної області застосування:
App.wife = Ember.Object.create({
householdIncome: 80000
});
App.husband = Ember.Object.create({
householdIncomeBinding: 'App.wife.householdIncome'
});
App.husband.get('householdIncome'); // 80000
// Someone gets raise.
App.husband.set('householdIncome', 90000);
App.wife.get('householdIncome'); // 90000
Зауважте, що прив'язки не оновлюються одразу. Ембер чекає, поки весь код вашої програми закінчиться, перш ніж синхронізувати зміни, тож ви можете змінити прив’язане властивість стільки разів, скільки хочете, не турбуючись про накладні витрати синхронізації, коли значення минущі.
Сподіваюсь, це допоможе розширити обрану оригінальну відповідь.
Варто зазначити, що існує багато різних рішень, які пропонують двосторонній зв'язок і дуже добре грають.
Я мав приємний досвід роботи з цією палітуркою моделі - https://github.com/theironcook/Backbone.ModelBinder . що дає розумні за замовчуванням ще чимало спеціального відображення вибору jquery атрибутів моделі для вхідних елементів.
Існує більш розширений список розширень / плагінів магістралей на github