Backbone.js:从集合中删除项目

时间:2012-04-16 17:10:18

标签: javascript backbone.js

我正在使用backbone.js来实现一个名为Roster的好友列表。我对名册集和个人rosterEntry的主干观点如下:

    Slx.Roster.Views.RosterEntry = Backbone.View.extend({
    tagName: "li",
    className : "rosterEntry clearfix",
    templateSelector: '#rosterEntryTemplate',

    initialize: function() {
        _.bindAll(this, 'render');
        this.model.bind('change', this.render);
        this.model.bind('remove', this.remove);
        this.template = _.template($("#rosterEntryTemplate").html());
    },

    remove: function () {
        debug.log("Called remove event on model");
        $(this.el).remove();
    },
    render: function() {
        var renderedContent = this.template(this.model.toJSON());
        this.id = this.model.Id;
        $(this.el).attr('id', "friendid-" + this.model.get("id")).html(renderedContent);
        return this;
    }
});

    Slx.Roster.Views.Roster = Backbone.View.extend({
        el: "div#roster-container",
        initialize: function () {
            _.bindAll(this, 'render', 'add', 'remove');
            this.template = _.template($("#rosterTemplate").html());
            this.collection.bind('reset', this.render);
            this.collection.bind('add', this.add);
            this.collection.bind('remove', this.remove);
        },
        add: function (rosterEntry) {
            var view = new Slx.Roster.Views.RosterEntry(
                {
                    model: rosterEntry
                });
            $(this.el).append(view.render().el);
        },
        remove: function (model) {  // if I ommit this then the whole collection is removed!!
            debug.log("called remomve on collection");
        },
        render: function () {
            var $rosterEntries, collection = this.collection;

            $(this.el).html(this.template({}));
            $rosterEntries = this.$('#friend-list');

            _.each(collection.models, function (model) {
                var rosterEntryView = new Slx.Roster.Views.RosterEntry({
                    model: model,
                    collection: collection
                });

                $(this.el).find("ul#friend-list").append(rosterEntryView.render().el);
            }, this);

            return this;
        }
    })

我现在正在使用Firebug控制台进行测试,并且可以通过执行以下命令来填充名单:

collection = new Slx.Roster.Collection
view = new Slx.Roster.Views.Roster({collection:collection})
collection.fetch()

通过在Firebug控制台中执行以下操作,添加到集合也可以正常工作:

collection.add(new Slx.Roster.Model({username:"mickeymouse"})

并将新的rosterEntry添加到名册中。

我的问题是collection.remove(5)从内存中的集合中删除,但没有更新DOM。

奇怪的是,如果我从名册视图中省略remove()函数,则会删除名单中的所有条目。如果我添加此方法除了控制台日志之外没有任何内容,则会调用名单和RosterEntry视图上的remove方法 - 虽然我不确定原因但是它们已经无序了!

["Called remove event on model"]
["called remomve on collection"]

如果我从RosterEntry模型中删除remove函数,我会收到此错误:

TypeError: this.$el is undefined
this.$el.remove();

我做错了什么?从集合中删除元素时如何从DOM中删除元素?

3 个答案:

答案 0 :(得分:2)

我认为您在每个事件绑定定义中都遇到context的问题。

尝试改变这一点:

this.model.bind('remove', this.remove);

为此:

this.model.bind('remove', this.remove, this);

我知道你试图用bindAll来解决这个问题,但是bindAll用实际对象的上下文来包装对列出的方法的每次调用,但这不能做任何事情如果你在其他对象上调用相同的方法:)。

更新

我阅读更多..看起来像bindAllbind命令的第三个参数完全相同。所以也许你可以使用其中一个。

因为无法使用bindAll中的model.remove,因为您忘记将其添加到_.bindAll(this, 'render')行,请查看代码。我的建议修正了它,因为我说两种方法都是一样的。

所做的一切是确保对所列方法的调用(在一个案例中为render, remove, ...或在另一个案例中为this.remove)将对this进行解释,作为对实际的参考宾语。这可能看起来很愚蠢,但JS中的this非常易变

如果您仍然对this事情感到困惑,请不要担心,我已经处理了很长时间但仍然not completely cofindent

也许essais like this可以帮助我们。

答案 1 :(得分:0)

您是否尝试过以下操作?

this.listenTo(this.model, "remove", this.remove);

这似乎对我有用,我喜欢它看起来更好一点的方式。

Link to Backbone doc

答案 2 :(得分:-1)

可能正在调用两个视图上的remove方法,因为您必须同时删除模型和集合。

在RosterEntry中:

 this.model.bind('remove', this.remove);

在名册中:

this.collection.bind('remove', this.remove);