tag link javascript data-binding backbone.js

javascript - link - tags html5



¿Qué es el enlace bidireccional? (5)

He leído muchas veces que Backbone no funciona en dos direcciones, pero no entiendo exactamente este concepto.

¿Podría alguien darme un ejemplo de cómo funciona el enlace bidireccional en una base de código MVC y cómo no funciona con Backbone?


En realidad, Ember compatible con el enlace bidireccional, que es una de las funciones más potentes para un framework javascript MVC. Puede consultarlo en donde menciona el binding en su guía del usuario.

para emberjs, crear enlaces bidireccionales es creando una nueva propiedad con la cadena Binding al final, y luego especificando una ruta desde el alcance global:

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

Tenga en cuenta que los enlaces no se actualizan de inmediato. Ember espera hasta que todo el código de la aplicación haya terminado de ejecutarse antes de sincronizar los cambios, por lo que puede cambiar una propiedad enlazada tantas veces como desee sin preocuparse por la sobrecarga de la sincronización de enlaces cuando los valores son transitorios.

Espero que ayude en la extensión de la respuesta original seleccionada.


La vinculación bidireccional significa que cualquier cambio relacionado con los datos que afecte al modelo se propaga inmediatamente a la (s) vista (s) coincidente, y que cualquier cambio realizado en la (s) vista (s) (por ejemplo, por el usuario) se refleja inmediatamente en el modelo subyacente . Cuando los datos de la aplicación cambian, también lo hace la UI, y viceversa.

Este es un concepto muy sólido sobre el que construir una aplicación web, ya que convierte la abstracción de "Modelo" en una fuente segura de datos atómicos para usar en cualquier lugar dentro de la aplicación. Digamos, si un modelo, vinculado a una vista, cambia, entonces su parte correspondiente de UI (la vista) reflejará eso, sin importar qué . Y la pieza correspondiente de la interfaz de usuario (la vista) se puede utilizar de forma segura como medio para recopilar datos / entradas del usuario, a fin de mantener actualizados los datos de la aplicación.

Una buena implementación de enlace bidireccional obviamente debe hacer que esta conexión entre un modelo y algunas vistas sea lo más simple posible, desde el punto de vista de un desarrollador.

Es bastante falso decir que Backbone no es compatible con el enlace bidireccional: aunque no es una característica central del framework, puede realizarse simplemente usando los eventos de Backbone. Cuesta algunas líneas explícitas de código para los casos simples; y puede volverse bastante peligroso para enlaces más complejos. Aquí hay un caso simple (código no probado, escrito sobre la marcha solo para ilustración):

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}

Este es un patrón bastante típico en una aplicación Backbone sin formato. Como se puede ver, requiere una cantidad decente de código (bastante estándar).

AngularJS y algunas otras alternativas ( Ember , Knockout ...) proporcionan enlaces bidireccionales como función de primer ciudadano. Resumen muchos casos extremos en algunos DSL, y hacen todo lo posible para integrar enlaces de dos vías dentro de su ecosistema. Nuestro ejemplo se vería así con AngularJS (código no probado, ver arriba):

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

¡Mas bien corto!

Pero tenga en cuenta que también existen algunas extensiones de enlace bidireccionales completamente desarrolladas para Backbone (en orden cruda y subjetiva de complejidad decreciente): Epoxy , Stickit , AngularJS ...

Una cosa interesante con Epoxy, por ejemplo, es que le permite declarar sus enlaces (atributos del modelo <-> elemento DOM de la vista) dentro de la plantilla (DOM) o dentro de la implementación de la vista (JavaScript). Algunas personas no les gusta agregar "directivas" a DOM / template (como los atributos ng- * requeridos por AngularJS o los atributos de enlace de datos de Ember).

Tomando Epoxy como ejemplo, uno puede volver a trabajar la aplicación Backbone sin procesar en algo como esto (...):

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}

En general, casi todos los marcos JS "mainstream" admiten enlaces bidireccionales. Algunos de ellos, como Backbone, requieren algún trabajo adicional para que funcione sin problemas , pero esos son los mismos que no hacen cumplir una forma específica de hacerlo, para empezar. Entonces, realmente se trata de tu estado de ánimo.

Además, es posible que le interese Flux , una arquitectura diferente para aplicaciones web que promueve el enlace unidireccional a través de un patrón circular. Se basa en el concepto de restitución rápida e integral de los componentes de la interfaz de usuario ante cualquier cambio de datos para garantizar la coherencia y facilitar la reflexión sobre el código / flujo de datos. En la misma tendencia, es posible que desee comprobar el concepto de MVI (Model-View-Intent), por ejemplo, Cycle .


La vinculación bidireccional solo significa que:

  1. Cuando las propiedades en el modelo se actualizan, también lo hace la UI.
  2. Cuando los elementos de la interfaz de usuario se actualizan, los cambios se propagan nuevamente al modelo.

El Backbone no tiene una implementación "horneada" de # 2 (aunque ciertamente puede hacerlo usando escuchas de eventos). Otros frameworks como Knockout sí se conectan de forma automática a enlaces bidireccionales .

En Backbone, puede lograr fácilmente el número 1 vinculando el método de "renderización" de una vista al evento de "cambio" de su modelo. Para lograr el n. ° 2, también debe agregar un detector de cambios al elemento de entrada y llamar a model.set en el controlador.

Aquí hay un Fiddle con enlace bidireccional configurado en Backbone.


McGarnagle tiene una gran respuesta, y querrás aceptar la suya, pero pensé que mencionaría (ya que preguntaste) cómo funciona la unión de datos.

En general, se implementa disparando eventos cada vez que se realiza un cambio en los datos, lo que hace que los oyentes (por ejemplo, la IU) se actualicen.

El enlace bidireccional funciona haciendo esto dos veces, con un poco de cuidado para garantizar que no termines atrapado en un bucle de evento (donde la actualización del evento provoca el lanzamiento de otro evento).

Iba a poner esto en un comentario, pero se estaba haciendo bastante largo ...


Vale la pena mencionar que hay muchas soluciones diferentes que ofrecen enlaces bidireccionales y juegan muy bien.

He tenido una experiencia agradable con esta carpeta modelo: AngularJS . que proporciona valores predeterminados razonables pero una gran cantidad de asignaciones de selector de jquery personalizadas de los atributos del modelo a los elementos de entrada.

Hay una lista más amplia de extensiones / complementos de github en github