0

我一整天都在面对一个问题,我有点绝望!我很确定这对于这里的一些 Backbone 专家来说会很简单......我是 Backbone 的新手,我可能没有采取最好的方法。任何帮助或建议都会很棒!

问题

将新项目添加到集合后,该集合被重新渲染,我可以看到新项目添加到我的 DOM。如果我单击“删除”按钮,则事件被触发,新项目被销毁......但元素保留在 DOM 中。如果我重新渲染页面(刷新或导航到其他地方并返回),它就消失了。

而如果我添加一个新项目,在我的集合被渲染后立即导航到其他地方,然后返回,然后按“删除”,这一次它会被销毁并从 DOM 中删除......有什么想法吗?

添加新项目

save: function(e){
    e.preventDefault();
    var data = form2js('deviceForm', '.', true);
    //Allow to create or edit a model;
    this.model.set(data);
    this.model = this.collection.create(this.model, {
        wait: true,
        success: function(){
            Utils.alert('success', 'Device has been added/edited');
            app.vent.trigger("devices:show");
        }
    });
}

此代码在我添加新项目时显示的视图内。添加新项目时,它会调用下面的函数。this.collection 是我的设备列表,在路由器内部重复使用。

路由器

showDevices: function(){
    if (!this.devices){
        this.devices = new Devices();
        this.devices.fetch();
    }
    if (this.devicesList) this.devicesList.remove();
    this.devicesList = new DevicesView({collection: this.devices});
    $('.addPadding').hide().slideDown(1000, 'linear').html(this.devicesList.render().el);
},

我只获取一次列表,然后在每次需要时重复使用它,避免不必要的获取。如果存在视图,我会清理视图并实例化一个新视图。

集合(查看)

initialize: function(){
    _.bindAll(this, "render", "addOne");

    this.collection.on('add', this.addOne);
    this.collection.on('reset', this.addAll);
},
render: function(){
    this.$el.html(this.template);
    this.addAll();
    return this;
},
addOne:function(device){
    var devi = new DeviceView({model: device});
    this.$el.find(".devices-list").append(devi.render().el);
},
addAll: function(){
    this.collection.each(this.addOne, this)
}

我的集合视图中没有定义 el 属性。绑定到集合事件,以便为新项目呈现或获取完成。

项目视图

tagName: 'tr',
events: {
    'click .remDevice': 'removeDevice',
    'click .editDevice' : 'editDevice'
},
template: _.template( template ),
initialize: function(){
    this.listenTo(this.model, 'destroy', this.remove);
},
render: function(){
    this.$el.html(this.template(this.model.toJSON()));
    return this;
},
removeDevice:function(){
    this.model.destroy();
}

我的项目被附加到表格中,到 tbody 元素。该表位于我的集合视图的模板中。当我单击删除按钮时,模型被销毁并触发事件并调用 this.remove。但是在创建项目后重新呈现集合时不起作用。虽然之后工作......

希望我提供了足够的信息!提前非常感谢!PS:控制台中没有错误,我的调试器中填充了模型+集合。

编辑: this.remove 在每次点击时都会被调用,因为我的模型每次都会被破坏。通过覆盖它并尝试手动删除元素:

this.$el.remove();

没有区别,也没有显示任何错误。this.$el 包含我新添加的元素。

编辑 2 一条新线索:如果我有 6 个设备的集合,添加第 7 个,然后尝试删除其中任何一个,除非我重新渲染,否则它们会被破坏但不会从 DOM 中删除。所以它不仅仅链接到新项目,而是我向集合中添加了一个新项目,渲染它并尝试删除一个项目。此外,编辑功能仍然适用于每个项目,并将我重定向到具有正确模型的正确页面进行编辑。

最后的编辑我试图清空集合之前添加新项目以避免僵尸......但没有改变任何东西。我希望它可以避免我的收藏视图中的随机副作用

addAll: function(){
                this.$el.find(".devices-list").empty();
                this.collection.each(this.addOne, this)
            },
4

1 回答 1

0

我找到了一种“肮脏”的方法来解决我的问题。我在“删除函数”中有一个断点。直观地比较 this.$el 和添加到表中的行是完全相同的行。

所以我试着这样做:

$('.devices-list').find(this.$el)

但是什么都没有返回……这太疯狂了,因为它们包含完全相同的数据!我假设 this.$el 以僵尸版本或其他形式呈现。我很确定这些项目的渲染方式有问题,以达到这一点......但我绝对找不到,我愿意接受建议......

解决方案

在我的Device View/Item View中,我编辑了这两个函数,将模型 id 添加到 tr 中,然后使用 jquery 在 DOM 中找到它。像这样,我专注于现有元素,而不是缓存 jquery 东西的 $el ......

render: function(){
        this.$el.html(this.template(this.model.toJSON()));
        this.$el.attr('id', this.model.id);
        return this;
    },
remove: function(){
            var elem =  $('.devices-list').find('#'+this.model.id);
            $(elem).find('#'+this.model.id).slideUp(1000);
            $(elem).find('#'+this.model.id).remove();
        }

希望有人会得到一个更好的主意,或者有人会从我的解决方案中得到帮助!

于 2013-05-10T01:41:22.103 回答