Update backbone view partially using timer in collection and get subset of a model

122 Views Asked by At

Am trying to update the some of the columns in table view when a timer triggered on collection am getting a subset of (only changed) properties. tried all kinds of codes from google but no luck.

Want to update only age property out of name and designation in view not intended to rerender the entire view.

here is my code

<div class='mainBody'>
        <table class="table">
            <tr class="success">
                <td>Name</td>
                <td>Age</td>
                <td>Ocupation</td>
            </tr>
        </table>
    </div>

    <script id="externalViewTemplate" type="text/template">

            <td width='25%'> <%= name %> </td>
            <td width='25%' id="age"> <%= age %> </td>
            <td width='25%'> <%= occupation %> </td>
    </script>

Script:

    //Person Model
var PersonModel = Backbone.Model.extend({
    _id:"id"
});

//Person collection - People
var PeopleCollection = Backbone.Collection.extend({
    model: PersonModel,
    view: PeopleView,
    initialize: function(){
        this.updateAge = setInterval(this.getAge.bind(this), 3000);
    },

    getAge: function()
    {
        var per = [{
                        id:1,
                        age: 31
                    },
                    {
                        id:2,
                        age: 32
                    },
                    {
                        id:3,
                        age: 37
                    }];
        this.reset(per);          
    }
});

//Person view - Responsible for rendering one person
var PersonView = Backbone.View.extend({
    tagName: 'tr',
    template: _.template( $('#externalViewTemplate').html() ),
    initialize: function() {
        this.model.on("change:age", this.update, this);
    },

    update: function() {
        this.el.cells["age"].innerHTML = this.model.get("age");
    },

    render: function(){
        this.$el.append(this.template(this.model.toJSON()));
        //console.log(this.$el.find('.edit'));
        return this;
    }
});

//person view collection - rendering the rows collection
var PeopleView = Backbone.View.extend({
    view: PersonView,
    initialize: function(options){
        this.collection = options.collection,
        this.collection.on("reset", this.update, this);
    },
    render: function(){
        this.collection.each(function(person){
            var personRow = new PersonView({model: person});
            this.$el.append(personRow.render().el);
        }, this);
    },

    update: function(){
        this.collection.each(function(person){
            //var personRow = new PersonView({model: person});
            this.model.age = person.age;
        }, this);
    }
});


//Try this code

var personCollection = new PeopleCollection([
    {
        id:1,
        name: 'Raju',
        age: 31,
        occupation: 'Dotnet Programmer'
    },
    {
        id:2,
        name: 'Rajesh',
        age: 32,
        occupation: 'Developer'
    },
    {
        id:3,
        name: 'Ramesh',
        age: 33,
        occupation: 'Designer'
    }
]
);

var peopleList = new PeopleView({ el: '.table', collection: personCollection});
peopleList.render();

Want to update only age property out of name and designation in view not intended to rerender the entire view.

1

There are 1 best solutions below

4
T J On

According to <tr> - MDN cells property returns an HTMLCollection. Your code for updating a cell should be

update: function() {
    this.el.cells.namedItem("age").innerHTML = this.model.get("age");
    // or this.el.cells.item(1).innerHTML = this.model.get("age");
    // this.el.cells[1].innerHTML = this.model.get("age"); might work
},

Since you most likely has jQuery with backbone, you can just do

this.$el.find(".age").text(this.model.get("age"));

Note that I use className "age" because you shouldn't use id in templates which gets duplicated. You can also use index(), eq() etc to access the cell using jQuery instead of className