拥有以下代码:
var Tasks = Backbone.Collection.extend({
url: 'http://localhost:5000/tasks'
});
var TaskView = Backbone.View.extend({
el: '.page',
render: function() {
var that = this;
var tasks = new Tasks();
tasks.fetch( {
success: function(tasks) {
var template = _.template($('#task-list-template').html(), {tasks: tasks.models});
that.$el.html(template);
}
})
}
});
var Router = Backbone.Router.extend({
routes: {
'' : 'home' // intentionally blank for the home page
}
});
// Display logic
var taskListView = new TaskView({ });
var router = new Router();
router.on('route:home', function() {
taskListView.render();
});
Backbone.history.start();
以下HTML:
<body>
<div class="container">
<h1>TODO app</h1>
<hr />
<div class="page"></div>
</div>
<script type="text/template" id="task-list-template">
<table class="table striped">
<thead>
<tr>
<th>Task</th>
<th></th>
</tr>
</thead>
<tbody>
<% _.each(tasks.tasks, function(task) { %>
<tr>
<td><%=task.get('task') %></td>
<td></td>
</tr>
<% }); %>
</tbody>
</table>
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script type="text/javascript" src="todoapp.js"></script>
</body>
以及从AJAX请求返回的以下JSON:
{
"tasks": [
{
"id": 6314025183,
"task": "1"
}
]
}
我想知道如何使用JSON数据填充Collection。我无法填写我的HTML表格。我怀疑我的收藏品没有被正确填写。
此代码基于来自Thomas Davis的视频,可在youtube上找到。 https://www.youtube.com/watch?v=FZSjvWtUxYk
答案 0 :(得分:3)
你有两个问题。一个是代码相关的,一个是遗憾的API相关。
API问题可以通过两种方式解决,但我会先解决它。
当Collection
请求数据(来自url
属性)时,它需要一个数据数组。不幸的是,您的API正在返回一个对象:
{
"tasks": [
{
"id": 6314025183,
"task": "1"
}
]
}
这在很多API设计中非常常见,并且真正说明了对API有用的一般误解。
您会注意到实际想要的数据位于对象的tasks
键中:
[
{
"id": 6314025183,
"task": "1"
}
]
它是一组任务对象,每个对象都有一个id
和 - 我认为是 - 一个任务id
。
很好,所以你有两个选择:你可以修复API,以便对像/tasks
这样的收集路由的请求返回集合:
[
{
"id": 6314025183,
"task": "1"
}
]
或者,您可以使用Backbone的parse
方法来破解垃圾数据。
来自Collection.parse
的文档:
如果您需要使用预先存在的API,或者更好地命名您的回复,请覆盖此内容。
这是一个简单的例子:
var Tasks = Backbone.Collection.extend({
'url': 'http://localhost:5000/tasks',
'parse': function( apiResponse ){
return apiResponse.tasks;
}
});
请注意该解析方法中包含的没有主页的信息。我怎么知道答复的关键是tasks
?
如果我是这位新代码的开发人员,那么我不会。我必须在API原始响应主体中搜索它的部落知识或知识。更好的解决方案是命名API响应以按要求返回集合。
您的第二个问题与您的代码有关。在您的代码中,您有一个Collection
和一个View
以及一个模板,但在您的模板中,您可以将您的任务视为一个简单的问题。 javascript对象,使用下划线循环键。
相反,请告诉您的收藏集如何表示数据。
集合是一组相关的Model
s。
var Task = Backbone.Model.extend({});
var Tasks = Backbone.Collection.extend({
'url': 'http://localhost:5000/tasks',
'model': Task,
'parse': function( apiResponse ){
return apiResponse.tasks;
}
});
现在,当您对集合进行保湿时,它将自动创建一个表示每组离散数据的模型。
您可以将视图更改为:
var TaskView = Backbone.View.extend({
'el': '.page',
'template': _.template($('#task-list-template').html()),
'render': function() {
var that = this;
var tasks = new Tasks();
tasks.fetch( {
success: function() {
that.$el.html( that.template( { 'tasks': tasks } ) );
}
})
}
});
由于所有Backbone对象都以某种方式扩展下划线(see the docs for the details),因此您不需要在下划线中手动包装传入的集合。事实上,这样做几乎总会产生错误。您的模板可能如下所示:
<html>
<body>
<div class="container">
<h1>TODO app</h1>
<hr />
<div class="page"></div>
</div>
<script type="text/template" id="task-list-template">
<table class="table striped">
<thead>
<tr>
<th>Task</th>
<th></th>
</tr>
</thead>
<tbody>
<% tasks.each( function( task ){ %>
<tr>
<td><%= task.get( 'task' ) %></td>
<td></td>
</tr>
<% }); %>
</tbody>
</table>
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script type="text/javascript" src="todoapp.js"></script>
</body>
</html>
此处发布的解决方案未经测试,但即使不能完全解决问题,也应该允许您进行主要的调试跳跃