Search code examples
javascriptajaxrestbackbone.js

unable to re-render the backbone view after saving the model


I save the model and I get a ok response from the server side that the DB is updated. What I'm trying to do is to refetch the collection and update the view with the saved model's information. I'm missing something minor but I just can't figure it out.

   $(document).ready(function () {
window.App = {
    Models: {},
    Collections: {},
    Views: {}
};

window.template = function(id){
    return _.template( $('#' + id).html() );
};


// Person Model
App.Models.Person = Backbone.Model.extend({
    defaults: {
        id: null,
        question: null,
        quizid: null,
        answerid: null
    },
     url: function() {
            return 'myurl/';
        }
});


App.Collections.People = Backbone.Collection.extend({
    model: App.Models.Person,
    url: 'myurl/'

});



App.Views.People = Backbone.View.extend({
    tagName: 'ul',

    render: function(){
        this.collection.each(function(person){
            var personView = new App.Views.Person({ model: person });
            this.$el.append(personView.render().el);
        }, this);

        return this;
    }
});


App.Views.Person = Backbone.View.extend({
    tagName: 'li',
    template: template('personTemplate'),
    events: {
     "click #saveButton" : "savedata",
    },


    savedata: function(event){
        //alert(this.model.get("id") + " " + $('#title').val());
                var newModel = new App.Models.Person();
                newModel.save({id: this.model.get("id"), question: $('#title').val()}, {
                    wait : true,
                    success: function (response) {
                        alert(response.responseText);
                        },
                        error: function (model, response) {
                            alert(response.responseText);
                        }
                    }
                );
    },

    render: function(){
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    }
});



var peopleCollection = new App.Collections.People;
peopleCollection.fetch({
    success: function(){
    var peopleView = new App.Views.People({collection: peopleCollection});
  $('body').append(peopleView.render().el);
}});


var pw = new peopleView({collection: personCollection});
pw.render();

Solution

  • If you want to refresh view after editing model data then you have to listen for a sync or change event and rerender the view.

    App.Views.Person = Backbone.View.extend({
        initialize: function(params) {
            this.listenTo(this.model, 'sync', this.render);
        }
    });
    

    In case you are adding a brand new model then you need to add it to the collection just after creating.

    newModel.save({id: this.model.get("id"), question: $('#title').val()} //...
    this.collection.add(newModel)
    

    and listen for add event in people view

    this.lisenTo(this.collection, 'add', this.render
    
    App.Views.People = Backbone.View.extend({
       initialize: function(params) {
           this.listenTo(this.collection, 'add remove sync', this.render);
       },
    
       render: function(){
           this.$el.empty();
    
           this.collection.each(function(person){
                var personView = new App.Views.Person({ model: person });
                this.$el.append(personView.render().el);
            }, this);
    
           return this;
        }
    });
    

    Refetching whole collection is redundant in that case.