我正在尝试创建一个Backbone模型(让我们称之为Library
),其中包含其他模型的集合(让我们称之为Books
)。我提供了一个视图 - LibraryView
,它创建了一个书籍案例的HTML,其中包含由BookView
生成的HTML表示的一组书籍。另外,我使用Handlebars.js作为我的模板系统。
我遇到的问题是,在我通过BookView
函数传递之前,我的render()
会在this.el元素上返回奇怪的html。
LibraryModel模型
var LibraryModel = Backbone.Model.extend({
initialize: function() {
var books = new BookCollection();
_.each(book_data.books, function(value, index) {
books.add(new Book());
});
this.books = books;
}
});
LibraryView视图:
var LibraryView = Backbone.View.extend({
el: "#library",
render: function() {
var t = this;
this.model.books.each(function(book, index) {
//create new view for each Book model in the books collection
var view = new BookView(book);
//append HTML produced by the BookView into LibraryView el element
t.$el.append(view.render().$el);
});
return this;
},
initialize: function() {
//snip
}
});
BookView查看:
var BookView = Backbone.View.extend({
render: function() {
var viewmodel = this.model;
var source = $("#book-template").html();
var template = Handlebars.compile(source);
var html = template(viewmodel.toJSON());
console.log(html); //prints <div test="wtf" anotherTest="123"><b>wtf</b> 123</div>
this.$el.html(html);
return this;
},
initialize: function(book) {
console.log(this.el.outerHTML); //prints <div test="wtf" anotherTest="123"></div>
this.model = book;
this.listenTo(this.model, "change", this.render);
}
});
我提供的模板是:<b>{{test}}</b> {{anotherTest}}
BookModel模型
var BookModel = Backbone.Model.extend({
defaults: {
test: "wtf",
anotherTest: 123
},
initialize: function() {
//snip
}
});
基本上,我遇到的问题是我的BookView
会生成奇怪的HTML,其中每个模型属性都附加到Backbone生成的div
,如下所示:
<div test="wtf" anotherTest="123">
<b>wtf</b> 123
</div>
我没有在代码中的任何其他位置设置任何属性 - 这两个值都只来自默认值。
另外,我确认这不是Handlebars正在做的事情,因为Model-attributes作为HTML-atributes插入到div
模型的Backbone生成BookView
中(注意,我没有提供tagName)或手动,我希望Backbone为我创建一个div。)
所以这就是我被困住的地方。我为BookView
为列表中的每个模型生成了一个完美的HTML列表,但由于某种原因,Backbone生成的div包装器在其HTML属性中包含每个Model属性,如下所示:
<div id="#library">
<div test="wtf" anotherTest="123"><b>wtf</b> 123</div>
<div test="wtf" anotherTest="123"><b>wtf</b> 123</div>
<div test="wtf" anotherTest="123"><b>wtf</b> 123</div>
</div>
我真的把头发拉过来,我怀疑它与我试图使用View-in-a-View的事实有关。
你以前遇到过类似的问题吗?你有很好的Backbone应用程序示例,其中MasterView呈现ChildViews的集合吗?
答案 0 :(得分:2)
创建新的BookViews
时,你做的很奇怪。该视图期望初始化BookModel
。但是,initialize()
方法始终需要按惯例调用attributes
的对象。您应修改BookView
,使其符合以下条件:
var BookView = Backbone.View.extend({
render: function() {
// keep the same code
},
initialize: function(attributes) {
this.listenTo(this.model, "change", this.render);
}
});
并在LibraryView
中使用:
var view = new BookView({ model : book });
而不是之前的:
var view = new BookView(film); // which is a typo, and should pass book and not film
所以现在你得到了预期的结果。
<div id="library">
<div><b>wtf</b> 123</div>
<div><b>wtf</b> 123</div>
<div><b>wtf</b> 123</div>
</div>
请注意,initialize(attributes)
会自动使用该映射调用set,因此您无需亲自调用set(attr, value)
。考虑到这一点,我们可以理解为什么该视图具有两个属性,这两个属性实际上是您的两个模型的属性(在初始化时它们是set()
。)