Enlace de datos bidireccional en backbone.js
(4)
Desde el sitio Backbone.js:
Se activará un evento de "cambio", a menos que se pase {silent: true} como una opción
options.silent = true;
container.model.set(this.attrName, this.value, options);
Actualización: Agregaste un nuevo comentario a tu pregunta, así que completé mi respuesta para arreglar el nuevo caso de uso (flujo de validación) que mencionaste:
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''});
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 elementos de entrada / widgets. 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.
container.model.set(this.attrName, this.value, options); // command 1
En la otra dirección, cuando el modelo se actualiza desde el backend, la vista del elemento / widget de entrada debería actualizarse automáticamente:
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 "source: 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 mejor solución? Muchas gracias por adelantado
Wolfgang
Actualizar:
Cuando se pasa la opción silent: true, no se llama al método de validación del modelo, por lo que no ayuda. Ver Backbone.js fuente 0.9.2:
_validate: function(attrs, options) {
if (options.silent || !this.validate) return true;
La vinculación bidireccional solo significa que:
- Cuando las propiedades en el modelo se actualizan, también lo hace la UI.
- Cuando los elementos de la interfaz de usuario se actualizan, los cambios se propagan nuevamente al modelo.
Backbone no tiene una implementación "horneada" de 2 opciones (aunque ciertamente puede hacerlo usando escuchas de eventos)
En Backbone, podemos lograr fácilmente la opción 1 vinculando el método "render" de una vista al 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 example con configuración de enlace bidireccional en Backbone.
Quería ver cuál sería el código básico para tener enlace bidireccional con Backbone.js. Esto es lo que se me 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 un jsbin para él: http://jsbin.com/guvusal/edit?html,js,console,output
He usado bibliotecas que hacen esto, como Epoxy.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.
Me interesarían las trampas potenciales y las mejoras que se podrían hacer con la clase TwoWayBoundView anterior (¡pero nada más allá del enlace bidireccional básico, por ejemplo, es decir, no estoy buscando más características para agregar).
Backbone.ModelBinder
complemento Backbone.ModelBinder
funciona muy bien para proporcionar enlace de datos bidireccional entre tus Vistas y Modelos Backbone. Escribí una publicación de blog que cubre algunas características esenciales de este complemento. Aquí está el enlace directo: http://niki4810.github.io/blog/2013/03/02/new-post/