不知道我哪里错了。我似乎无法获取模板来在嵌套的json中呈现标题属性。我正在按照一个在线教程,有点牵着我的手,但我碰到了一堵砖墙,无法弄清楚它为什么不会渲染。任何帮助将不胜感激。
这是我的模板和HTML。
<script id="albumTemplate" type="text/template">
<p><%= title %></p>
</script>
<script id="subalbumTemplate" type="text/template">
<p><%= title %></p>
</script>
<div class="row">
<div class="six columns"><h5>Albums</h5></div>
<div class="six columns"><h5>Sub-Albums</h5></div>
</div>
<div class="row" style="color: #333;">
<div class="six columns" id="categories"></div>
<div class="six columns" id="sub-cat"></div>
</div>
这是我的app.js
app.Subalbum = Backbone.Model.extend({
initialize: function () {
this.subId = this.get('id');
this.subTitle = this.get('title');
this.subImg = this.get('image');
this.subCanvas = this.get('canvas');
this.subSize = this.get('size');
}
});
app.Subalbums = Backbone.Collection.extend({
model: app.Subalbum
});
app.Album = Backbone.Model.extend({
initialize: function () {
this.subs = new app.Subalbums(this.get('subalbum'));
this.subs.parent = this;
this.albumId = this.get('id');
this.albumTitle = this.get('title');
this.albumImg = this.get('image');
}
});
app.Albums = Backbone.Collection.extend({
model: app.Album,
url: 'albums.json',
parse: function (data) {
return data;
}
});
app.AlbumCollectionView = Backbone.View.extend({
el: $("#categories"),
initialize: function () {
_.bindAll(this, 'render');
this.model.on('reset', function () {
this.render();
}, this);
},
render: function (event) {
_.each(this.model.models, function (album) {
//console.log(album.subs);
$(this.el).append(new app.AlbumView({
model: album
}).render().el);
}, this);
return this;
}
});
app.AlbumView = Backbone.View.extend({
template: _.template($("#albumTemplate").html()),
initialize: function () {
_.bindAll(this, 'render');
// Subalbum View should be instantiated and called from inside the initialize function of the Parent View
this.subView = new app.SubalbumView({
model: this.model.subs
});
this.subView.parentView = this; // this assignment connects the child view to the parent view
$("#sub-cat").append(this.subView.render().el); // subView should "return this" from child render() function
},
render: function () {
//console.log(this.model.subs);
//$(this.el).html("<p>" + this.model.get("title") + "</p>");
$(this.el).append(this.template(this.model.toJSON()));
return this;
}
});
app.SubalbumView = Backbone.View.extend({
template: _.template($("#subalbumTemplate").html()),
initialize: function () {
_.bindAll(this, 'render');
this.model.on('reset', function () {
this.render();
}, this);
},
render: function (event) {
_.each(this.model.models, function (subalbum) {
$(this.el).append("<p>" + subalbum.get("title") + "</p>");
//$(this.el).html(this.template(subalbum.toJSON()));
}, this);
return this;
}
});
app.AlbumRouter = Backbone.Router.extend({
routes: {
"": "indexRoute"
},
indexRoute: function () {
this.albumList = new app.Albums();
this.albumList.fetch();
this.albumAppView = new app.AlbumCollectionView({
model: this.albumList
});
}
});
var albumRoute = new app.AlbumRouter();
Backbone.history.start();
这是albums.json文件结构。
[
{
"pid":0,
"title":"Blues Singer",
"image":"blues_singer.jpg",
"subalbum":[
{
"pid":0,
"title":"Another Realm",
"image":"another_realm.jpg"
},
{
"pid":1,
"title":"Ascendant",
"image":"ascendant.jpg"
},
{
"pid":2,
"title":"Ascent",
"image":"ascent.jpg"
}
]
},
{
"pid":1,
"title":"Destiny",
"image":"destiny.jpg",
"subalbum":[
{
"pid":0,
"title":"Cathedral of Trees",
"image":"cathedral_of_trees.jpg"
},
{
"pid":1,
"title":"Come Up Here",
"image":"come_up_here.jpg"
},
{
"pid":2,
"title":"Crystal Forest",
"image":"crystal_forest.jpg"
}
]
},
{
"pid":2,
"title":"Eagle",
"image":"eagle.jpg",
"subalbum":[
{
"pid":0,
"title":"Curved Road",
"image":"curved_road.jpg"
},
{
"pid":1,
"title":"Dawn Breaking",
"image":"dawn_breaking.jpg"
},
{
"pid":2,
"title":"Dawn",
"image":"dawn.jpg"
}
]
},
{
"pid":3,
"title":"Evening Harvest",
"image":"evening_harvest.jpg",
"subalbum":[
{
"pid":0,
"title":"Destiny",
"image":"destiny.jpg"
},
{
"pid":1,
"title":"Destiny2",
"image":"destiny2.jpg"
},
{
"pid":2,
"title":"Eagle Rising",
"image":"eagle_rising.jpg"
}
]
}
]
答案 0 :(得分:1)
问题是您等待来自reset
的{{1}}事件,但默认情况下不会触发this.albumList.fetch()
,因此您需要将reset
传递给{ {1}}。这是JSFIDDLE。
{reset:true}
一些建议(我将选择你的fetch
),但同样适用于你的其他观点:
您可以只使用字符串indexRoute: function () {
this.albumList = new app.Albums();
// This view will render when the model's reset event is triggered.
// Since albumList is a collection, it should identified as such.
this.albumAppView = new app.AlbumCollectionView({
// albumList is a collection and it should identified as such.
// instead of model:this.albumList - now within albumAppView, you will have
// access to the collection via this.collection instead of this.model
collection: this.albumList
});
this.albumList.fetch({reset:true});
}
AlbumCollectionView
。
在el: $("#categories")
中,当您可以利用listenTo时,您正在使用el:'#categories'
。使用initialize
的主要优点是在视图上调用this.model.on
时,会为您清理事件侦听器。
listenTo
转到remove
函数后,// this works.
this.collection.on('reset', function () {
this.render();
}, this);
// can be written as (remember the we changed model to collection above).
this.listenTo(this.collection,'reset',this.render);
附加了underscore methods个render
。
Backbone.Collection
// while this works
_.each(this.collection.models, function (album) { ... });
// can be written as:
this.collection.each(function(album) { ... });
});
,有点过时了,您可以使用$(this.el)
,它只是视图元素的缓存jQuery对象。 $el documentation
所以,当我们把它们放在一起时,最终会结束:
this.$el