양방향 바인딩이란 무엇입니까?


173

Backbone이 양방향 바인딩을 수행하지 않는 것을 많이 읽었지만이 개념을 정확하게 이해하지 못합니다.

누군가가 MVC 코드베이스에서 양방향 바인딩이 작동하는 방식과 Backbone에서 어떻게 작동하지 않는지에 대한 예를 들어 줄 수 있습니까?

답변:


249

양방향 바인딩은 다음을 의미합니다.

  1. 모델의 속성이 업데이트되면 UI도 업데이트됩니다.
  2. UI 요소가 업데이트되면 변경 사항이 모델로 다시 전파됩니다.

백본에는 # 2의 "베이크 인 (baked-in)"구현이 없습니다 (확실히 이벤트 리스너를 사용하여 수행 할 수 있음). 녹아웃과 같은 다른 프레임 워크 는 자동으로 양방향 바인딩을 연결합니다 .


Backbone에서는 뷰의 "렌더링"메소드를 모델의 "변경"이벤트에 바인딩하여 쉽게 # 1을 달성 할 수 있습니다. # 2를 달성하려면 입력 요소에 변경 리스너를 추가 model.set하고 핸들러를 호출 해야합니다.

다음 은 백본에 양방향 바인딩이 설정된 바이올린 입니다.


25
당신이 그것을 본 후에 대답은 너무 고통스럽게 분명하다. 시간을내어 명확한 답변과 모범을 보여 주셔서 감사합니다.
Chris M

그리고 Firebase와 함께 제공됩니다 ... 3-way databinding-> View, Model, Database. 꽤 깔끔하다고 생각했습니다.
Levi Fuller

간결하고 짧습니다. +1
Karan_powered_by_RedBull

46

양방향 바인딩은 모델에 영향을 미치는 모든 데이터 관련 변경 사항이 즉시 일치하는보기로 전파 되고보기에서 변경 한 내용 (예 : 사용자가 변경 한 내용)이 즉시 기본 모델에 반영됨 을 의미합니다. . 앱 데이터가 변경되면 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)의 개념을 확인하려고 할 수 있습니다 .


3
많은 개발자, 특히 React / Flux 개발자는 양방향 바인딩이 대규모 앱을 빌드하기위한 안전한 패턴을 고려하지 않습니다.
Andy

28

McGarnagle은 큰 대답을 가지고 있으며, 그를 받아들이고 싶을 것입니다.하지만 데이터 바인딩이 어떻게 작동하는지 언급 한 것으로 생각했습니다.

일반적으로 데이터가 변경 될 때마다 이벤트를 발생시켜 리스너 (예 : UI)를 업데이트합니다.

양방향 바인딩은 이벤트 루프 (이벤트 업데이트로 인해 다른 이벤트가 발생하는 경우)에 걸리지 않도록 약간의주의를 기울여이 작업을 두 번 수행함으로써 작동합니다.

나는 이것을 주석에 넣을 것이었지만 꽤 길어지고 있었다 ...


2

실제로 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는 변경 사항을 동기화하기 전에 모든 응용 프로그램 코드의 실행이 끝날 때까지 대기하므로 값이 일시적 일 때 바인딩 동기화의 오버 헤드에 대해 걱정하지 않고 원하는만큼 바인딩 된 속성을 변경할 수 있습니다.

선택한 원래 답변을 확장하는 데 도움이되기를 바랍니다.


1

양방향 바인딩을 제공하고 실제로 훌륭하게 재생하는 다양한 솔루션이 있다는 점을 언급 할 가치가 있습니다.

이 모델 바인더 인 https://github.com/theironcook/Backbone.ModelBinder에 대해 즐거운 경험을했습니다 . 이것은 합리적인 기본값을 제공하지만 모델 속성을 입력 요소에 매핑하는 많은 사용자 정의 jquery 선택기 매핑을 제공합니다.

github 에는 더 확장 된 백본 확장 / 플러그인 목록이 있습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.