2012-09-26 18 views
11

Estoy desarrollando una aplicación web jQuery Backbone.js.
Como está en Adobe Flex, he implementado el enlace de datos bidireccional en mi aplicación para los elementos/widgets de entrada . Por lo tanto, cada elemento/widget de entrada conoce su modelo y nombre de atributo de modelo correspondientes.
Cuando el usuario toca la pestaña o ingresa, el valor del campo se asigna automáticamente al modelo.Enlace de datos bidireccional en backbone.js

container.model.set(this.attrName, this.value, options); // command 1 

En la otra dirección, cuando el modelo se actualiza desde el servidor, la vista del elemento entrada/artilugios deben automáticamente actualización:

container.model.bind("change:"+ this.attrName, this.updateView, this); // command 2 

El problema es:
Cuando el usuario pulsa enter y el modelo se actualiza automáticamente, también se activa el "change: abc" y se llama a this.updateView, no solo cuando un nuevo modelo proviene del back-end .

Mi solución hasta ahora era pasar una opción "fuente: gui" cuando establecía el valor del modelo cuando el usuario presiona enter (comando 1), y para verificarlo en mi método updateView. Pero ya no estoy satisfecho con esta solución.

¿Alguien tiene una solución mejor? Muchas gracias de antemano
Wolfgang

Actualización:
Cuando la opción de silencio: se pasa cierto, el método de validación del modelo no se llama, por lo que no ayuda. Véase la procedencia Backbone.js 0.9.2:

_validate: function(attrs, options) { 
    if (options.silent || !this.validate) return true; 

Respuesta

7

De Backbone.js sitio:

A se dispara evento "cambio", a menos que {silenciosa: true} se pasa como una opción

options.silent = true; 
container.model.set(this.attrName, this.value, options); 

actualización: Ha añadido un nuevo comentario a la pregunta, así que sólo complementa mi respuesta para fijar el nuevo CAS uso e (flujo de validación) que usted ha mencionado:

var ExtendedModel = Backbone.Model.extend({ 
    uiChange : false, 
    uiSet: function (attributes, options, optional) { 
     this.uiChange = true; 
     this.set(attributes, options, optional); 
     this.uiChange = false; 
    } 
}); 

var MyModel = ExtendedModel.extend({ 
}); 

var model = new MyModel(); 
model.on('change:name', function(){ 
    console.log('this.uiChange: ', this.uiChange); 
}); 

//simulates the server side set 
model.set({name:'hello'}); 

//simulates the ui side set you must use it to set from UI 
model.uiSet({name:'hello2'}); 
+0

Gracias Daniel. Pero con esta opción, no se llama a "validar". Entonces no me ayuda. –

+0

Hola, Wolfgang, vi tu nueva actualización y agregué una solución. =) –

2

Backbone.ModelBinder plugin funciona grande para proporcionar la unión entre sus Vistas Backbone y modelos de datos bidireccional. Me escribió una entrada de blog que cubre algunas de las características esenciales de este plugin Aquí está el enlace directo: http://niki4810.github.io/blog/2013/03/02/new-post/

6

dos vías de unión sólo significa que:

  1. Cuando propiedades en el modelo se actualizan, lo mismo ocurre con la interfaz de usuario.
  2. Cuando los elementos de la IU se actualizan, los cambios se propagan al modelo .

Backbone no tiene una aplicación "en horneada" de 2 opción (aunque ciertamente puede hacerlo utilizando detectores de eventos)

En Backbone, podemos lograr fácilmente la opción 1 uniéndose a fin de " el método "render" para el evento de "cambio" de su modelo. Para lograr la opción 2, también debe agregar un detector de cambios al elemento de entrada y llamar a model.set en el controlador.

check (jsfiddle.net/sunnysm/Xm5eH/16)jsfiddle ejemplo con enlace bidireccional configurado en Backbone.

0

Quería ver cuál sería el código básico para tener enlace bidireccional con Backbone.js. Esto es lo que ocurrió:

var TwoWayBoundView = Backbone.View.extend({ 
    initialize: function(options) { 
     this.options = _.defaults(options || {}, this.options); 
     _.bindAll(this, "render"); 
     this.model.on("change", this.render, this); 
     this.render(); 
    }, 

    events: { 
     "change input,textarea,select": "update" 
    }, 

    // input updated 
    update: function(e) { 
     this.model.set(e.currentTarget.id, $(e.currentTarget).val()); 
    }, 

    // model updated...re-render 
    render: function(e) { 
     if (e){ 
      var id = Object.keys(e.changed)[0]; 
      $('#'+id).val(e.changed[id]); 
     } 
     else{ 
      _.each(this.model.attributes, function(value, key){ 
       $('#'+key).val(value); 
      }); 
     } 
    } 
}); 

Y el uso:

var model = new Backbone.Model({ prop1: "uno 1", prop2: "dos 2", prop3: "3" }); 
var view = new TwoWayBoundView({ 
    el: "#myContainer", 
    model: model 
}); 

Aquí hay una jsbin para ello: http://jsbin.com/guvusal/edit?html,js,console,output

He usado bibliotecas que hacen esto, como epoxi. js (solo 11k minificado). Y hay varios otros además, que recomendaría mucho antes de usar el código de prueba de concepto anterior.

estaría interesado en peligros potenciales y mejoras que se podrían hacer con la clase TwoWayBoundView anterior (pero nada allá de unión a favor de dos vías básico! Decir que estoy no buscando más características para agregar)

Cuestiones relacionadas