如何解析此JSON以用于Backbone View

时间:2017-05-22 14:22:37

标签: javascript json backbone.js

我试图学习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>

2 个答案:

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

其他信息