保存模型时更新主干视图

Update a Backbone view when model is saved

本文关键字:视图 更新 模型 保存      更新时间:2023-09-26

我有以下场景-

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

我定义了一个模型和相应的集合。

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;
    }
});

上面的视图为每个模型创建一个单独的列表项。

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();
    }
});

在WineView中,当表单的提交按钮被点击时,模型被保存。骨干。同步功能被重写。

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();

我担心的是,当模型保存时,WineListView不会刷新并显示已添加的新模型。确切地说,this.mode.bind("add")不会被调用。

我为这个问题的冗长而道歉。但是,这件事已经困扰了我一个星期了。非常感谢任何帮助。

干杯!

add从未被调用的原因正是如此一旦您的葡萄酒保存了wine.save();,您应该添加一个成功函数并将其添加到酒单集合

试试这个:

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');
    }
});

关于事件聚合器想法的更多信息请查看此:
backbone.js中的路由和事件聚合器协调视图

据我所知,您从未真正新模型添加到集合中。一种简单的方法是使用集合的create方法(假设您已经使集合可用):

save_form: function () {
    this.collection.create({ MODEL ATTRIBUTES HERE … });
    return false;
}

如文档所述

[t] create方法既可以接受属性散列,也可以接受已存在的未保存的模型对象。

创建这样的新模型,应该触发一个add事件在集合上,如果我没有弄错的话。

另一种方法,根据文档,它肯定会触发add事件(同样,在集合上,而不是模型上!)

save_form: function () {
    var wine = new Wine();
    this.collection.add(wine);
    return false;
}

向集合添加一个模型(或一个模型数组)。触发一个"添加"事件,您可以通过{silent: true}来抑制该事件。

无论如何,记得更改事件绑定:

this.collection.bind("add", function (wine) {
    alert("model added");
});