답변:
양방향 바인딩은 다음을 의미합니다.
백본에는 # 2의 "베이크 인 (baked-in)"구현이 없습니다 (확실히 이벤트 리스너를 사용하여 수행 할 수 있음). 녹아웃과 같은 다른 프레임 워크 는 자동으로 양방향 바인딩을 연결합니다 .
Backbone에서는 뷰의 "렌더링"메소드를 모델의 "변경"이벤트에 바인딩하여 쉽게 # 1을 달성 할 수 있습니다. # 2를 달성하려면 입력 요소에 변경 리스너를 추가 model.set
하고 핸들러를 호출 해야합니다.
양방향 바인딩은 모델에 영향을 미치는 모든 데이터 관련 변경 사항이 즉시 일치하는보기로 전파 되고보기에서 변경 한 내용 (예 : 사용자가 변경 한 내용)이 즉시 기본 모델에 반영됨 을 의미합니다. . 앱 데이터가 변경되면 UI도 변경됩니다.
이것은 "모델"추상화를 응용 프로그램 내 어디에서나 사용할 수있는 안전한 원자 데이터 원본으로 만들기 때문에 웹 응용 프로그램을 구축하기위한 매우 견고한 개념입니다. 뷰에 바인딩 된 모델이 변경되면 일치하는 UI (뷰)가 무엇이든 관계없이 반영합니다 . 그리고 일치하는 UI (보기)는 애플리케이션 데이터를 최신 상태로 유지하기 위해 사용자 입력 / 데이터를 수집하는 수단으로 안전하게 사용할 수 있습니다.
좋은 양방향 바인딩 구현은 분명히 개발자의 관점에서 모델과 일부 뷰 사이의 연결을 가능한 한 간단하게 만들어야합니다.
백본이 양방향 바인딩을 지원 하지 않는다고 말하는 것은 사실 이 아닙니다 . 프레임 워크의 핵심 기능은 아니지만 백본의 이벤트를 사용하여 아주 간단하게 수행 할 수 있습니다. 간단한 경우에는 몇 줄의 코드가 필요합니다. 더 복잡한 바인딩에는 상당히 위험 할 수 있습니다. 다음은 간단한 사례입니다 (예상 목적으로 만 작성된 테스트되지 않은 코드).
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에 대한 본격적인 양방향 바인딩 확장 도 존재 합니다 (복잡성이 감소하는 원시적이고 주관적인 순서로) : Epoxy , Stickit , ModelBinder ...
예를 들어, 에폭시의 멋진 점 중 하나는 템플릿 (DOM) 또는 뷰 구현 (JavaScript) 내에서 바인딩 (모델 속성 <-> 뷰의 DOM 요소)을 선언 할 수 있다는 것입니다. 어떤 사람들은 DOM / 템플릿에 "지시문"을 추가하는 것을 싫어합니다 (예 : AngularJS에 필요한 ng- * 속성 또는 Ember의 데이터 바인딩 속성).
에폭시를 예로 들어, 원시 백본 애플리케이션을 다음과 같이 재 작업 할 수 있습니다 (…).
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 프레임 워크는 양방향 바인딩을 지원합니다. Backbone과 같은 일부는 원활하게 작동하기 위해 약간의 추가 작업이 필요 하지만 처음 에는 특정 방법을 강요하지 않는 것과 동일합니다. 그래서 그것은 당신의 마음 상태에 관한 것입니다.
또한 원형 패턴을 통해 단방향 바인딩을 촉진하는 웹 응용 프로그램을위한 다른 아키텍처 인 Flux에 관심이있을 수 있습니다 . 데이터 변경시 UI 구성 요소를 빠르고 전체적으로 다시 렌더링한다는 개념을 기반으로하여 응집력을 보장하고 코드 / 데이터 흐름에 대한 추론을 쉽게합니다. 같은 추세에서 Cycle 과 같은 MVI (Model-View-Intent)의 개념을 확인하려고 할 수 있습니다 .
실제로 emberjs
자바 스크립트 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
바인딩은 즉시 업데이트되지 않습니다. Ember는 변경 사항을 동기화하기 전에 모든 응용 프로그램 코드의 실행이 끝날 때까지 대기하므로 값이 일시적 일 때 바인딩 동기화의 오버 헤드에 대해 걱정하지 않고 원하는만큼 바인딩 된 속성을 변경할 수 있습니다.
선택한 원래 답변을 확장하는 데 도움이되기를 바랍니다.
양방향 바인딩을 제공하고 실제로 훌륭하게 재생하는 다양한 솔루션이 있다는 점을 언급 할 가치가 있습니다.
이 모델 바인더 인 https://github.com/theironcook/Backbone.ModelBinder에 대해 즐거운 경험을했습니다 . 이것은 합리적인 기본값을 제공하지만 모델 속성을 입력 요소에 매핑하는 많은 사용자 정의 jquery 선택기 매핑을 제공합니다.
github 에는 더 확장 된 백본 확장 / 플러그인 목록이 있습니다