Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update a Backbone view when model is saved

I have the following scenario -

window.Wine = Backbone.Model.extend({
  urlRoot: '/wines'

});
window.WineCollection = Backbone.Collection.extend({
   model: Wine,
   url: "/wines"
});

I have a model and the respective collection defined.

window.WineListView = Backbone.View.extend({
    el: '#wineList',
    initialize: function () {
        this.model.bind("reset", this.render, this);
        this.model.bind("add", function (wine) {
            alert("model added");
        });
    },
    render: function (eventName) {
        _.each(this.model.models, function (wine) {
            $(this.el).append(new WineListItemView({
                model: wine
            }).render().el);
        }, this);
        return this;
    }
});
window.WineListItemView = Backbone.View.extend({
    tagName: "li",
    initiliaze: function () {
        this.render();
    },
    render: function (eventName) {
        var template = _.template($('#wine-list-item').html());
        $(this.el).html(template(this.model.toJSON()));
        return this;
    }
});

The above views creates an individual list item for each model.

window.WineView = Backbone.View.extend({
    el: $("#mainArea"),
    initialize: function () {
        this.render();
    },
    render: function (eventName) {
        var template = _.template($("#wine-details").html(), {});
        $(this.el).html(template);
    },
    events: {
        "click #save_form": "save_form"
    },
    save_form: function () {
        var wine = new Wine();
        wine.save();
        return false;
    }
});
window.HeaderView = Backbone.View.extend({
    el: '.header',
    initialize: function () {
        this.render();
    },
    render: function (eventName) {
        var template = _.template($('#header').html());
        $(this.el).html(template());
        return this;
    },
    events: {
        "click .new": "newWine"
    },
    newWine: function (event) {
        var wine_View = new WineView();
        wine_View.render();
    }
});

In WineView, when the submit button of the form is clicked the model is saved. The Backbone.sync function is overridden.

var AppRouter = Backbone.Router.extend({
    routes: {
        "": "list"
    },
    list: function () {
        this.wineList = new WineCollection();
        this.wineListView = new WineListView({
            model: this.wineList
        });
        this.wineList.fetch();
    }
});
var app = new AppRouter();
Backbone.history.start();
var header = new HeaderView();

My concern is, when the model is saved the WineListView doesn't get refreshed and show the new model that has been added. Precisely the this.mode.bind("add") doesn't get invoked.

I apologize for the verbosity of the question. But, this has been bothering me a for almost a week. Any help is greatly appreciated.

Cheers!

like image 219
verdure Avatar asked Jan 02 '12 06:01

verdure


People also ask

Why use Backbone js?

BackboneJS allows developing of applications and the frontend in a much easier way by using JavaScript functions. BackboneJS provides various building blocks such as models, views, events, routers and collections for assembling the client side web applications.

How does Backbone js work?

Backbone. js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.

What is Backbone in programming?

Backbone. js is a model view controller (MVC) Web application framework that provides structure to JavaScript-heavy applications. This is done by supplying models with custom events and key-value binding, views using declarative event handling and collections with a rich application programming interface (API).


1 Answers

the reason add is never called is exactly that once your wine is saved wine.save(); you should add a success function and add it to the winelist collection

try this:

wine.save(wine.toJSON(), {
    success: function(){ 
        // model was saved successfully, now add it to the collection
        yourwinelist.add(wine);
        // if you can't access your wine list from this context, you might want to raise an event, and pass the wine, to catch it somewhere else:
        obj.trigger('myWineAdded', wine); // this can be raised on a global event aggregator
    },
    error: function(){ 
        // handle app when saving to server fails
        alert('failed to save wine');
    }
});

more info on the event aggregator idea check this :
Routing and the event aggregator coordinating views in backbone.js

like image 60
Sander Avatar answered Oct 06 '22 01:10

Sander