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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10178540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 08:55:16  来源:igfitidea点击:

Backbone.js : Remove an item from a collection

javascriptbackbone.js

提问by reach4thelasers

I'm using backbone.js to implement a buddy list aka Roster. My backbone view for the Roster collection and individual rosterEntryare as follows:

我正在使用backbone.js 来实现一个好友列表又名名册。我对名册集合和个人的主干视图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"})

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

and the new rosterEntryis 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. If I add this method with nothing in it but a console log, it the remove method on both the Roster and RosterEntryviews is called - although I'm not sure why but they are out of order!

奇怪的是,如果我remove()从名册视图中省略该功能,名册中的所有条目都将被删除。如果我添加此方法时除了控制台日志之外什么都没有,则会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 中移除元素?

采纳答案by fguillen

I think you have a problem with the contextin 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 bindAllis 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正在使用实际对象的上下文包装对列出的方法的每次调用,但是如果您在其他对象上调用相同的方法,这将无济于事:)。

Updated

更新

I have reading more.. looks like bindAlland the third paramater of the bindcommand do exactly the same. So maybe you can use the one or the other.

我读了更多……看起来bindAllbind命令的第三个参数完全一样。所以也许你可以使用一个或另一个。

The becauseis not working the bindAllin the model.removeis because you forgot to add it to the _.bindAll(this, 'render')line, look in your code. And my suggestion fixed it because as I say both approachs do the same.

因为不工作bindAllmodel.remove,因为你忘了把它添加到_.bindAll(this, 'render')您的代码行,看看。我的建议修复了它,因为正如我所说,两种方法的作用相同。

What all this is doing is assuring that the calls to the listed methods (render, remove, ...in one case or this.removein the other) are gonna interpretate thisas a reference to the actual object. This can look stupid but thisis very volatilein JS.

这一切所做的是确保对列出的方法的调用(render, remove, ...在一种情况下或this.remove另一种情况下)将解释this为对实际对象的引用。这看起来很愚蠢,但在 JS 中this非常不稳定

Don't worry if you are still confused with the thisthing, I have dealing with it for long and still not completely cofindent.

如果您仍然对这this件事感到困惑,请不要担心,我已经处理了很长时间,仍然没有完全确定

Maybe essais like thiscan help us.

也许像这样的散文可以帮助我们。

回答by moliveira

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 文档

回答by Marty Cortez

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:

在名册条目中:

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

In Roster:

在名册中:

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