我试图学习Backbone并且似乎无法将fetch功能中的数据匹配到我的Underscore模板中。如何在JSON中获取子数组并将其与模板匹配?
Backbone.View看起来像这样:
var Projects = Backbone.Collection.extend({
url: '/tree/projects'
});
var Portfolio = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var projects = new Projects();
projects.fetch({
success: function (projects) {
var template = _.template($('#projects-template').html());
that.$el.html(template({projects: projects.models}));
}
})
}
});
在网址:http://localhost:3000/portfolio/api/tree/projects
返回的JSON如下所示:
{
id:"projects",
url:"http://localhost:8888/portfolio/projects",
uid:"projects",
title:"Projects",
text:"",
files:[
],
children:[
{
id:"projects/example-1",
url:"http://localhost:8888/portfolio/projects/example-1",
uid:"example-1",
title:"Example 1",
images:"",
year:"2017",
tags:"Website",
files:[
],
children:[
]
},
{
id:"projects/example-2",
url:"http://localhost:8888/portfolio/projects/example-2",
uid:"example-2",
title:"Example @"2
text:"Example 2's text",
year:"2016",
tags:"Website",
files:[
{
url:"http://localhost:8888/portfolio/content/1-projects/4-example-2/example_ss.png",
name:"example_ss",
extension:"png",
size:244845,
niceSize:"239.11 kB",
mime:"image/png",
type:"image"
}
],
children:[
]
},
]
}
My Underscore文件如下所示:
<script type="text/template" id="projects-template">
<h4>tester</h4>
<div>
<% _.each(projects.children, function (project) { %>
<div>
<div><%= project.get('year') %></div>
<div><%= project.get('title') %></div>
<div><%= project.get('tags') %></div>
</div>
<% }); %>
</div>
</script>
答案 0 :(得分:2)
您可以在集合上定义解析方法:
linearlayout
答案 1 :(得分:1)
parse
虽然我通常同意with TJ,但对集合使用解析更像是一个黑客而不是一个明确的解决方案。它只能用于获得项目的子项目,仅此而已。
parse
函数不应该对集合产生副作用,使用这种方法,更改和保存父项目中的字段将不会轻易成为可能
它也没有处理它是嵌套结构的事实,它不仅仅是一个包装好的数组。
此功能在接收包装数据时效果最佳:
{
data: [{ /*...*/ }, { /*...*/ }]
}
您在这里拥有嵌套项目的项目。项目应该是一个模型。您还有文件,因此您应该拥有File
模型。
获取每个资源并使用它创建模型和集合类。但首先,请将共享数据排除在外。
var API_ROOT = 'http://localhost:8888/';
var FileModel = Backbone.Model.extend({
defaults: {
name: "",
extension: "png",
size: 0,
niceSize: "0 kB",
mime: "image/png",
type: "image"
}
});
var FileCollection = Backbone.Collection.extend({
model: FileModel
});
var ProjectModel = Backbone.Model.extend({
defaults: function() {
return {
title: "",
text: "",
files: [],
children: []
};
},
getProjects: function() {
return this.get('children');
},
setProjects: function(projectArray, options) {
return this.set('children', projectArray, options);
},
getFiles: function() {
return this.get('files');
},
getSubProjectUrl: function() {
return this.get('url');
}
});
var ProjectCollection = Backbone.Collection.extend({
model: ProjectModel,
url: API_ROOT + '/tree/projects'
});
然后,查看项目。这是一个简单的示例,请参阅有关优化渲染的提示的其他信息。
var ProjectView = Backbone.View.extend({
template: _.template($('#projects-template').html()),
initialize: function(options) {
this.options = _.extend({
depth: 0, // default option
}, options);
// Make a new collection instance with the array when necessary
this.collection = new ProjectCollection(this.model.getProjects(), {
url: this.model.getSubProjectUrl()
});
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
this.$projectList = this.$('.list');
// use the depth option to avoid rendering too much projects
if (this.depth > 0) this.collection.each(this.renderProject, this);
return this;
}
renderProject: function(model) {
this.$projectList.append(new ProjectView({
model: model,
depth: depth - 1
}).render().el);
}
});
使用这样的模板:
<script type="text/template" id="projects-template">
<h4><%= title %></h4>
<span><%= year %></span><span><%= tags %></span>
<p><%= text %></p>
<div class="list"></div>
</script>
使用视图:
var model = new ProjectModel({ id: "project" });
model.fetch({
success: function() {
var project = new ProjectView({
model: model,
depth: 2
});
}
});