I'm developing a jQuery Backbone.js web application.
As it is in Adobe Flex, I have implemented 2 way data binding in my app for
input elements/widgets.
So, every input element/widget knows its corresponding model and model attribute name.
When the user hits tab or enter, the field value is automatically given to the model.
container.model.set(this.attrName, this.value, options); // command 1
In the other direction, when the model gets updated from the backend, the view of the input element/widget should automatically get updated:
container.model.bind("change:"+ this.attrName, this.updateView, this); // command 2
The problem is:
When the user hits enter and the model is automatically updated, also the "change:abc" is
triggered and this.updateView is called, not only when a new model comes from the
backend.
My solution until now was to pass an option "source: gui" when setting the model value when the user pressed enter (command 1), and to check for that in my updateView method. But I am not content with this solution anymore.
Does anybody have a better solution?
Thanks alot in advance
Wolfgang
Update:
When the option silent: true is passed, the validate method of the model is not called, so
that does not help. See Backbone.js source 0.9.2:
_validate: function(attrs, options) {
if (options.silent || !this.validate) return true;
From Backbone.js site:
A "change" event will be triggered, unless {silent: true} is passed as an option
options.silent = true;
container.model.set(this.attrName, this.value, options);
Update: You added a new comment to your question, so I just complemented my answer to fix the new use case(validation flow) that you mentioned:
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'});