有以下代码:
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 数据填充集合。我无法填写 HTML 表格。我怀疑我的收藏没有正确填写。
- 如何验证集合的内容?
- 我是否以正确的方式填充集合?
此代码基于 Thomas Davis 在 YouTube 上提供的这段视频。 https://www.youtube.com/watch?v=FZSjvWtUxYk
最佳答案
你有两个问题。一种是与代码相关的,另一种是与 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
的文档:
Override this if you need to work with a preexisting API, or better namespace your responses.
这是一个简单的示例:
var Tasks = Backbone.Collection.extend({
'url': 'http://localhost:5000/tasks',
'parse': function( apiResponse ){
return apiResponse.tasks;
}
});
请注意该解析方法中包含的信息,该方法没有 home。我如何知道响应的关键是 tasks
?
如果我是刚接触此代码的新开发人员,那么事实是我不会。这是部落知识或我必须在 API 原始响应正文中搜索的知识。更好的解决方案是为 API 响应命名空间以按请求返回集合。
<小时/>您的第二个问题与您的代码有关。在您的代码中,您有一个 Collection
和一个 View
以及一个模板,但在您的模板中,您将任务视为普通的 ol' javascript 对象,使用下划线来处理循环一个键。
相反,告诉您的集合如何表示其数据。
集合是一组相关的模型
。
var Task = Backbone.Model.extend({});
var Tasks = Backbone.Collection.extend({
'url': 'http://localhost:5000/tasks',
'model': Task,
'parse': function( apiResponse ){
return apiResponse.tasks;
}
});
现在,当您对集合进行水合时,它会自动创建一个代表每组离散数据的模型。
您可以将 View 更改为如下所示:
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>
此处发布的解决方案未经测试,但即使不能完全解决问题,也应该允许您进行重大调试飞跃
关于javascript - 如何从 JSON 填充 Backbone 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33045036/