javascript - 如何从 JSON 填充 Backbone 集合

标签 javascript json backbone.js-collections

有以下代码:

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 表格。我怀疑我的收藏没有正确填写。

  1. 如何验证集合的内容?
  2. 我是否以正确的方式填充集合?

此代码基于 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/

相关文章:

json - postman 原始数据有效,但表单数据不适用于 Node 中的 POST 请求

javascript - ES6/TS/Angular2 将 JSON 解析为 Date

Python - 如何将 json 对象数组转换为 Dataframe?

javascript - 无损 Backbone 集合过滤

javascript - 数据表中的多列过滤器( Bootstrap )

javascript - Angular: bool @Input 与 Attribute @Directive - 使用哪个?

javascript - Backbone.js + Require.js : Collection URL set, 但出现错误 "Uncaught Error: A "url“必须指定属性或函数”

javascript - Backbone 集合模型 self 复制

javascript - 滚动到顶部 Jquery 不工作

javascript - 每次我再次运行时,动画变得越来越快