2

我正在为我的项目使用 Backbone.js。
抱歉,我是 Backbone 新手,因此我可能会遗漏一些非常琐碎的东西。

这是一个 HTML 片段:

<table id="notes" class="table">
    <thead>
        <tr><th>title</th><th>comment</th></tr>
    </thead>
    <tbody id="notesTableBody">
    </tbody>
</table>

这是应该在该片段中“注入” HTML 的主干代码:

App.view.NoteListView = Backbone.View.extend({

    el:"tbody#notesTableBody",

    initialize:function () {
        this.model.bind("reset", this.render, this);
    },

    render:function (eventName) {
        _.each(this.model.models, function (note) {
            $(this.el).append(new App.view.NoteListItemView({model:note}).render().el);
        }, this);
        return this;
    }

});

为了清楚起见,我没有粘贴NoteListItemView代码,因为我认为它不相关。

我的问题是Backbone渲染的HTML代码如下:

<table id="notes" class="table">
    <tbody id="notesTableBody">
    <tr><td>title 1</td><td>comment 1</td></tr>
    </tbody>
</table>

基本上,Backbone 从桌子上移除了头。
我不明白为什么 - 我如何确保 Backbone 不会删除它?

4

1 回答 1

4

NoteListView不会在它之外写任何东西el(例如:http: //jsfiddle.net/ambiguous/cFvX2/)所以你的问题在别处。

我的猜测是您正在做与此等效的事情:

var v = new App.view.NoteListView;
$('#notes').html(view.render().el);

这将完全用(即's )替换#notes表格的内容。<tbody>NoteListViewel

有几种方法可以解决您的问题。您可以调用render并忽略它返回的内容:

var v = new App.view.NoteListView;
v.render();

这几乎就是我的第一个演示小提琴所做的。

或者您可以使用idandtagName而不是el

App.view.NoteListView = Backbone.View.extend({
    id: 'notesTableBody',
    tagName: 'tbody',
    initialize:function () {
        this.model.bind("reset", this.render, this);
    },
    render:function (eventName) {
        _.each(this.model.models, function (note) {
            $(this.el).append(new App.view.NoteListItemView({model:note}).render().el);
        }, this);
        return this;
    }
});

然后append视图el$('#notes')

var v = new App.view.NoteListView;
$('#notes').append(v.render().el);

演示:http: //jsfiddle.net/ambiguous/HTAkM/

您还可以让调用者指定el

App.view.NoteListView = Backbone.View.extend({
    initialize:function () {
        this.model.bind("reset", this.render, this);
    },
    render: function(eventName) {
        _.each(this.model.models, function (note) {
            $(this.el).append(new App.view.NoteListItemView({model:note}).render().el);
        }, this);
        return this;
    }
});

然后render进入el而不关心render' 的返回值:

var v = new App.view.NoteListView({ el: $('#notesTableBody') });
v.render();

演示:http: //jsfiddle.net/ambiguous/2Ptkp/


当我在这里时,您不再需要$(this.el),最新版本的 Backbone 提供this.$el您的观点:

$el view.$el

视图元素的缓存 jQuery(或 Zepto)对象。一个方便的参考,而不是一直重新包装 DOM 元素。

如果您的视图正在包装一个集合,您应该使用this.collection而不是this.model

new SomeView({ collection: some_collection })

视图特别对待collection选项,就像model

构造函数/初始化 new View([options])

[...] 有几个特殊选项,如果通过,将直接附加到视图:modelcollectionelidclassName和。tagNameattributes

Backbone 集合也混合了几个 Underscore 方法,所以你不需要这么说:

_.each(some_collection.models, function(m) { ... });

您可以each在集合上致电:

some_collection.each(function(m) { ... });

此外,如果您要绑定到一个"reset"事件:

this.model.bind("reset", this.render, this);

你可能希望你在添加更多东西之前render清除它:el

render: function() {
    this.$el.empty();
    this.collection.each(function(note) { ... });
}

如果你不这样做,当你可能打算用新东西替换它的内容时,你会添加更多的东西emptyel

于 2012-05-23T21:54:24.887 回答