Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js auto render view after destroy

I have the 2 views for my model. One creates the ul view, the other add the li elements. The views work but they do not update after the destroy function is called. I've tried various ways to bind to the render function, but it is not being called after this.model.destroy(); What am I missing?

var NoteListView = Backbone.View.extend({

    tagName:'ul', 
    className: 'note-group',

    initialize:function () {

        _.bindAll(this, "render");    // I've tried all these:
        this.model.bind("change", this.render, this);
        this.model.bind("destroy", this.render, this);
        this.model.bind("reset", this.render, this);
        this.model.bind('change', _.bind(this.render, this));
        this.model.on('change',this.render,this);
    },
    render:function (eventName) {
        _.each(this.model.models, function (note) {
            $(this.el).append(new NoteListItemView({
                model:note
            }).render().el);
        }, this);
        return this;
    }

});

var NoteListItemView = Backbone.View.extend({

    tagName:"li", 
    className: 'note-item',

    template:_.template($('#tpl-note-item').html()),
    initizlize:function(){
        this.model.on('change',this.render,this);
    },
    render:function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },
    events: {
        "click .note-btn-delete": "deleteNote"
    },
    deleteNote: function(e){
        this.model.destroy();
    }
});  

Edit: here's the Collection:

var NoteCollection = Backbone.Collection.extend({
    model:Note,
    url:"api.php/notes",
    initialize: function (models){
        this.filtered = new Backbone.Collection(models);
    },
    filterByCid: function(id) {
        var filtered = _.filter(this.models, function (model) {
            if (id==0) return true;
            return model.get("contactid") == id;
        });
    }
});

In the router:

this.noteList = new NoteCollection();
            this.noteList.fetch({data:{contactid:id},
                success: function (collection){
                    if (collection.length>0){
                            $('#note-container').html(new NoteListView({model:collection}).render().el);
                        }
                        else {
                            $('#note-container').html('No notes');
                        }
                }
            })
like image 351
mozgras Avatar asked Sep 01 '26 05:09

mozgras


1 Answers

I see 2 issues with your code.

First

You are not listening to the remove event on the NodeListItemView

Second

 _.each(this.model.models,

supposed to be

 _.each(this.collection.models,

If models is present on the model, then it is supposed to be in the options of the model

 _.each(this.model.options.models,

Code

var NoteListView = Backbone.View.extend({

    tagName: 'ul',
    className: 'note-group',
    initialize: function () {
         this.listenTo.on(this.collection, 'reset', this.render);
    },
    render: function (eventName) {
        _.each(this.collection.models, function (note) {
            $(this.el).append(new NoteListItemView({
                model: note
            }).render().el);
        }, this);
        return this;
    }

});

var NoteListItemView = Backbone.View.extend({
    tagName: "li",
    className: 'note-item',

    template: _.template($('#tpl-note-item').html()),
    initizlize: function () {
        _.bindAll(this, "deleteNote", "removeView");
        this.listenTo.on(this.model, 'change', this.render);
        this.listenTo.on(this.model, 'remove', this.removeView);
    },
    render: function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },
    events: {
        "click .note-btn-delete": "deleteNote"
    },
    deleteNote: function (e) {
        this.model.destroy();
    },
    removeView : function() {
        this.remove();
    }
});

EDIT

Change this line

new NoteListView({model:collection}).render().el

to use collection instead

new NoteListView({collection :collection}).render().el

And I do not believe your fetch method takes in any data

    this.noteList.fetch({data:{contactid:id})

    this.noteList.fetch()

It only takes in success and error callbacks

like image 97
Sushanth -- Avatar answered Sep 05 '26 11:09

Sushanth --



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!