我如何解析此 JSON 以便在 Backbone 视图中使用

How can I parse this JSON for use in Backbone View

我正在努力学习 Backbone,但似乎无法将提取函数中的数据匹配到我的 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}));
            }
        })
    }
});

在 url: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:[  

         ]
      },
   ]
}

我的 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>

您可以在集合上定义一个解析方法:

var Projects = Backbone.Collection.extend({
  url: '/tree/projects',
  parse: function(response){
    /* save other data from response directly to collection if needed.
     for eg this.title = response.title; */
    return response.children; // now models will be populated from children array
  }
});

不要使用parse

虽然我通常同意 ,但对集合使用解析更像是一种 hack,而不是确定的解决方案。它只能获取项目的子项目,仅此而已。

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
        });
    }
});

附加信息