Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two way data binding in backbone.js

Tags:

backbone.js

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;
like image 244
Wolfgang Adamec Avatar asked Sep 26 '12 15:09

Wolfgang Adamec


People also ask

How can I get two-way binding in JavaScript?

To create a two-way data binding, we will create an object's property with a getter and a setter function. Mainly the setter function of the object to update the value of the corresponding HTML element. We will be using Object. defineProperty to define the getter and setter for an object's property.

What is a two-way data binding?

Two-way binding gives components in your application a way to share data. Use two-way binding to listen for events and update values simultaneously between parent and child components.

Which of the following is a common example of two-way data binding?

Examples of Two-Way Data Binding use include Buttons, Text Boxes, Tabs, and Sliders.

Which of the following can be used to create two-way data bindings?

Two-way data binding can be achieved using a ngModel directive in Angular. The below syntax shows the data binding using (ngModel), which is basically the combination of both the square brackets of property binding and parentheses of the event binding.


3 Answers

Two-way binding just means that:

  1. When properties in the model get updated, so does the UI.
  2. When UI elements get updated, the changes get propagated back to the model.

Backbone doesn't have a "baked-in" implementation of 2 option (although you can certainly do it using event listeners)

In Backbone, we can easily achieve option 1 by binding a view's "render" method to its model's "change" event. To achieve option 2, you need to also add a change listener to the input element, and call model.set in the handler.

check (jsfiddle.net/sunnysm/Xm5eH/16)jsfiddle example with two-way binding set up in Backbone.

like image 144
Sunny S.M Avatar answered Dec 09 '22 13:12

Sunny S.M


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'});
like image 38
Daniel Aranda Avatar answered Dec 09 '22 14:12

Daniel Aranda


Backbone.ModelBinderplugin works great for providing Two-way data binding between your Backbone Views and Models. I wrote a blog post covering some essential features of this plugin Here is the direct link: http://niki4810.github.io/blog/2013/03/02/new-post/

like image 38
Nikhil Avatar answered Dec 09 '22 14:12

Nikhil