【问题标题】:Backbone.js : Remove an item from a collectionBackbone.js :从集合中删除一个项目
【发布时间】:2012-04-16 17:10:17
【问题描述】:

我正在使用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;
        }
    })

我现在正在使用 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() 函数,名册中的所有条目都会被删除。如果我添加这个方法,除了控制台日志之外什么都没有,它会调用 Roster 和 RosterEntry 视图上的 remove 方法 - 虽然我不知道为什么,但它们有问题!

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

如果我从 RosterEntry 模型中删除删除功能,我会收到此错误:

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

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

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    我认为每个事件绑定定义中的 context 都有问题。

    尝试改变这一点:

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

    为此:

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

    我知道你已经尝试使用bindAll 来解决这个问题,但是bindAll 正在使用实际对象的上下文包装对列出的方法的每个调用,但是如果你调用 其他对象上的相同方法 :)。

    更新

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

    因为model.remove 中的bindAll 不起作用是因为您忘记将其添加到_.bindAll(this, 'render') 行,请查看您的代码。我的建议解决了这个问题,因为正如我所说的两种方法都一样。

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

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

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

    【讨论】:

    • 你的意思是我对每个 eventet 绑定定义都有问题?不确定我是否真的了解 bindall 对你说实话。我只是认为所有事件都必须添加到 bindall。
    • bind函数上的第三个参数代表什么?
    • 这成功了!谢谢!认为我已经通过阅读另一篇 stackoverflow 帖子了解了 bindall 的用途,但为什么 bindall 不起作用?它似乎做同样的事情......还有为什么我不需要在集合绑定语句上额外添加一个“this”?
    • @reach4thelasers 我已经用更多解释扩展了答案,也许它有助于回答你的问题。
    • 如果您有兴趣,这里是另一个主干.js 问题stackoverflow.com/questions/10192325/…
    【解决方案2】:

    您是否尝试过以下方法?

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

    这似乎对我有用,我更喜欢它的阅读方式。

    Link to Backbone doc

    【讨论】:

      【解决方案3】:

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

      在名册条目中:

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

      在名册中:

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

      【讨论】:

        猜你喜欢
        • 2011-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-12
        • 2013-01-17
        • 1970-01-01
        相关资源
        最近更新 更多