简体   繁体   English

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

[英]Backbone.js : Remove an item from a collection

I'm using backbone.js to implement a buddy list aka Roster. 我正在使用backbone.js来实现一个名为Roster的好友列表。 My backbone view for the Roster collection and individual rosterEntry are as follows: 我对名册收集和独立的骨干视图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;
        }
    })

I'm testing for now using the Firebug console and can populate the roster just fine by executing the following: 我正在使用Firebug控制台进行测试,并且可以通过执行以下命令来填充名单:

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

Adding to a collection also works fine, by executing the following in the Firebug console: 通过在Firebug控制台中执行以下操作,添加到集合也可以正常工作:

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

and the new rosterEntry is added to the Roster. 并将新的rosterEntry添加到名册中。

My problem is that collection.remove(5) removes from the in-memory collection, but does nothing to update the DOM. 我的问题是collection.remove(5)从内存中的集合中删除,但没有更新DOM。

Strangely, if I ommit the remove() function from the Roster View, all the entries in the roster are removed. 奇怪的是,如果我从名单视图中省略了remove()函数,则会删除名单中的所有条目。 If I add this method with nothing in it but a console log, it the remove method on both the Roster and RosterEntry views is called - although I'm not sure why but they are out of order! 如果我添加此方法除了控制台日志之外没有任何内容,则会调用Roster和RosterEntry视图上的remove方法 - 虽然我不确定为什么但是它们不正常!

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

if I delete the remove function from the RosterEntry model I get this error: 如果我从RosterEntry模型中删除remove函数,我会收到此错误:

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

What am I doing wrong? 我究竟做错了什么? How do I remove the element from the DOM when it is removed from the collection? 从集合中删除元素时如何从DOM中删除元素?

I think you have a problem with the context in every event bind definition. 我认为每个事件绑定定义中的context都有问题。

Try to change this: 试着改变这个:

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

For this: 为了这:

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

I know you have tried to solve this with the bindAll , but bindAll is wrapping every call to the listed methods with the context of the actual object, but this can't do anything if you are calling the same method on other object :). 我知道你试图用bindAll来解决这个bindAll ,但是bindAll用实际对象的上下文来包装对列出的方法的每次调用,但如果你在其他对象上调用相同的方法 ,这就无法做任何事情:)。

Updated 更新

I have reading more.. looks like bindAll and the third paramater of the bind command do exactly the same. 我阅读更多..看起来像bindAllbind命令的第三个参数完全相同。 So maybe you can use the one or the other. 所以也许你可以使用其中一个。

The because is not working the bindAll in the model.remove is because you forgot to add it to the _.bindAll(this, 'render') line, look in your code. 因为不正常的bindAllmodel.remove是因为你忘了把它添加到_.bindAll(this, 'render')行,看在你的代码。 And my suggestion fixed it because as I say both approachs do the same. 我的建议修正了它,因为我说两种方法都是一样的。

What all this is doing is assuring that the calls to the listed methods ( render, remove, ... in one case or this.remove in the other) are gonna interpretate this as a reference to the actual object. 这一切都做的是确保该所列出的方法调用( render, remove, ...在一个案件或this.remove的除外)都打算interpretate this为实际对象的引用。 This can look stupid but this is very volatile in JS. 这看起来愚蠢,但是this是在JS非常不稳定

Don't worry if you are still confused with the this thing, I have dealing with it for long and still not completely cofindent . 如果你仍然this件事情感到困惑,请不要担心,我已经处理了很长时间而且还没有完全结合

Maybe essais like this can help us. 也许这样的essais可以帮助我们。

Have you tried the following? 你试过以下吗?

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

That seems to work for me and I like the way it reads a little bit better. 这似乎对我有用,我喜欢它看起来更好一点的方式。

Link to Backbone doc 链接到Backbone doc

The remove methods on both the views are probably being called because you've bound to remove on both the model and the collection. 可能正在调用两个视图上的remove方法,因为您必须同时删除模型和集合。

In RosterEntry: 在RosterEntry中:

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

In Roster: 在名册中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM