[javascript] Was ist in beide Richtungen verbindlich?



Answers

Zweiwege-Bindung bedeutet, dass alle datenbezogenen Änderungen, die das Modell beeinflussen, sofort an die übereinstimmenden Ansichten weitergegeben werden und dass alle Änderungen, die in den Ansichten (z. B. vom Benutzer) vorgenommen werden, sofort im zugrunde liegenden Modell widergespiegelt werden . Wenn sich die App-Daten ändern, ändert sich auch die Benutzeroberfläche und umgekehrt.

Dies ist ein sehr solides Konzept zum Aufbau einer Webanwendung, da es die "Modell" -Abstraktion zu einer sicheren, atomaren Datenquelle macht, die überall in der Anwendung verwendet werden kann. Angenommen, ein Modell, das an eine Ansicht gebunden ist, ändert sich, und das entsprechende Stück Benutzeroberfläche (die Ansicht) spiegelt das wider, egal was passiert . Und das passende Stück UI (die Ansicht) kann sicher als Mittel zum Sammeln von Benutzereingaben / Daten verwendet werden, um die Anwendungsdaten auf dem neuesten Stand zu halten.

Eine gute bidirektionale Bindungsimplementierung sollte diese Verbindung zwischen einem Modell und einigen Ansichten aus entwicklerischer Sicht offensichtlich so einfach wie möglich machen.

Es ist dann ziemlich unwahr zu sagen, dass Backbone keine bidirektionale Bindung unterstützt: Obwohl es kein Kernmerkmal des Frameworks ist, kann es jedoch einfach mit Backbones Events durchgeführt werden. Es kostet ein paar explizite Codezeilen für die einfachen Fälle; und kann für komplexere Bindungen ziemlich gefährlich werden. Hier ist ein einfacher Fall (ungeprüfter Code, der nur zur Veranschaulichung geschrieben wurde):

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}

Dies ist ein ziemlich typisches Muster in einer rohen Backbone-Anwendung. Wie man sehen kann, benötigt es eine anständige Menge an (ziemlich normalem) Code.

AngularJS und einige andere Alternativen ( Ember , Knockout ...) bieten eine Zwei-Wege-Bindung als First-Citizen-Feature. Sie abstrahieren viele Edge-Cases unter einigen DSL und tun ihr Bestes, um die Zweiwege-Bindung in ihr Ökosystem zu integrieren. Unser Beispiel würde mit AngularJS (nicht getesteter Code, siehe oben) in etwa so aussehen:

<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: ''}

Recht kurz!

Aber Stickit , AngularJS es auch für Backbone einige vollwertige Stickit Bindungserweiterungen gibt (in roher, subjektiver Reihenfolge abnehmender Komplexität): Epoxy , Stickit , AngularJS ...

Eine coole Sache mit Epoxy ist zum Beispiel, dass Sie Ihre Bindungen (Modellattribute <-> Ansichts-DOM-Element) entweder innerhalb des Templates (DOM) oder innerhalb der View-Implementierung (JavaScript) deklarieren können. Manche Leute mögen es nicht, dem DOM / Template "Direktiven" hinzuzufügen (wie die von AngularJS benötigten ng- * Attribute oder die Datenbindungsattribute von Ember).

Am Beispiel von Epoxy kann man die rohe Backbone-Anwendung in etwas ähnliches umwandeln (...):

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}

Alles in allem unterstützen so ziemlich alle "Mainstream" JS-Frameworks die Zwei-Wege-Bindung. Einige von ihnen, wie Backbone, benötigen etwas zusätzliche Arbeit, um es reibungslos funktionieren zu lassen, aber das sind die gleichen, die zu Beginn keine spezifische Vorgehensweise erzwingen. Es geht also wirklich um deinen Gemütszustand.

Möglicherweise interessieren Sie sich auch für Flux , eine andere Architektur für Webanwendungen, die eine einseitige Bindung durch ein kreisförmiges Muster fördert. Es basiert auf dem Konzept der schnellen, ganzheitlichen Neudarstellung von UI-Komponenten bei jeder Datenänderung, um Kohärenz zu gewährleisten und den Code / Datenfluss einfacher zu verstehen. Im selben Trend möchten Sie vielleicht das Konzept von MVI (Model-View-Intent) überprüfen, zum Beispiel Cycle .

Question

Ich habe gelesen, dass Backbone nicht in beide Richtungen bindet, aber ich verstehe dieses Konzept nicht genau.

Könnte mir jemand ein Beispiel dafür geben, wie eine Zweiwege-Bindung in einer MVC-Codebasis funktioniert und wie es nicht mit Backbone funktioniert?




Eigentlich unterstützt Ember Zwei-Wege-Bindung, die eine der mächtigsten Funktionen für ein Javascript-MVC-Framework ist. Sie können überprüfen, wo es binding in seiner Bedienungsanleitung erwähnt.

Für Emberjs wird eine Zwei-Wege-Bindung erstellt, indem eine neue Eigenschaft mit der Zeichenfolge Binding am Ende erstellt und dann ein Pfad aus dem globalen Bereich angegeben wird:

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

Beachten Sie, dass Bindungen nicht sofort aktualisiert werden. Ember wartet, bis der gesamte Anwendungscode ausgeführt wurde, bevor die Änderungen synchronisiert werden. Daher können Sie eine gebundene Eigenschaft so oft ändern, wie Sie möchten, ohne sich um den Overhead der Synchronisierungsbindungen kümmern zu müssen, wenn Werte vorübergehend sind.

Hoffe, es hilft im Umfang der ursprünglichen Antwort ausgewählt.




Related