Javascript 将JSON映射到backbone.js集合

Javascript 将JSON映射到backbone.js集合,javascript,json,backbone.js,backbone.js-collections,Javascript,Json,Backbone.js,Backbone.js Collections,好吧,看起来我需要一个提示来指引我正确的方向。这个问题分为两部分——处理多维JSON和JSON中的集合集合 背景 我有一些将从服务器检索的JSON,可以控制如何格式化 多维JSON 我无法将模型连接到JSON中的部分。假设我只想在下面的示例JSON中呈现每个帖子的作者姓名和状态内容。我在将状态输入到模型中没有问题,但是作者的名字我有点困惑如何进入它。根据我的理解,我必须重写解析 这是不是很糟糕的标准/我是否应该使用更好的JSON结构?把它尽量放平会更好吗?那就是将作者姓名和照片上移一级 我在读书

好吧,看起来我需要一个提示来指引我正确的方向。这个问题分为两部分——处理多维JSON和JSON中的集合集合

背景 我有一些将从服务器检索的JSON,可以控制如何格式化

多维JSON 我无法将模型连接到JSON中的部分。假设我只想在下面的示例JSON中呈现每个帖子的作者姓名和状态内容。我在将状态输入到模型中没有问题,但是作者的名字我有点困惑如何进入它。根据我的理解,我必须重写解析

这是不是很糟糕的标准/我是否应该使用更好的JSON结构?把它尽量放平会更好吗?那就是将作者姓名和照片上移一级

我在读书,但我还是有点不清楚

收藏中的收藏 在backbone.js的集合中创建集合有什么好方法吗?我将有一个帖子的集合,然后将有一个关于该帖子的评论集合。当我在主干网中发展时,这是可能的吗

根据我在和中的理解,它看起来是这样的

var Comments = Backbone.Model.extend({
    defaults : {
      _id : "",
      text : "",
      author : ""
    }
})

var CommentsCollection = Backbone.Collection.extend({ model : Comments })

var Posts = Backbone.Model.extend({
    defaults : {
        _id : "",
        author : "",
        status : "",
        comments : new CommentsCollection
    }
})

var PostsCollection = Backbone.Collection.extend({ model : Posts })
示例JSON 我很感激你给我的任何提示。谢谢

(编辑以纠正我最初对问题的误读。)

不需要重写模型的
parse
方法,除非您想更改其结构。但听起来您不需要——要呈现作者名称,只需在视图中使用
author.name

<%= author.name %>
注意,您需要在
Posts
模型的
initialize
方法中执行类似的操作——检索comments JSON数组,并将其转换为
comments
模型的数组:

initialize: function() {
    if (attributes.comments && attributes.comments.length > 0) {
        var commentModels = attributes.comments.map(function(comment) { 
            return new Comments(comment); 
        });
        this.set("comments", new CommentsCollection(commentModels));
    }
}

当试图编写代码以使其适用于嵌套对象时,可能会让人不知所措。但是为了使它更简单,让我们把它分解成更小的可管理的部分

我会这样想

收藏

 Posts
 Comments
 Post
 Comment
 Author
型号

 Posts
 Comments
 Post
 Comment
 Author

Posts集合中的每个模型将有3组属性(可能不是正确的术语)

第一级-属性级别(状态、id)

第二个-作者属性,可放置在单独的模型(Authod模型)中

第三,收集每个帖子模型的评论

收藏中的收藏在这里可能会有点混乱。 因为集合中有模型(
Post-Model-inside-Posts-Collection
),每个模型将再次嵌套一个集合(
Comments-Collection-inside-Post-Model
)。基本上,您将在模型中处理
集合

根据我的理解,我必须重写解析

这是不是很糟糕的标准/我是否应该使用更好的JSON结构

在Parse方法中处理这个过程是一个非常合理的解决方案。初始化集合或模型时,首先调用Parse方法,然后调用initialize。因此,在Parse方法内部处理逻辑是完全合乎逻辑的,而且这根本不是一个坏标准

把它尽量放平会更好吗

我不认为把这个单位保持在一个水平是一个好主意,因为其他数据在第一个水平上是不需要的

因此,我解决这个问题的方法是在
Post-Model
中编写
parse
方法,该方法处理响应并将Author-Model和Comments集合直接附加到模型上,而不是作为模型上的一个属性,以保持由第一级Post数据组成的属性散列干净。从长远来看,我觉得这将更干净,更具可扩展性

var postsObject = [{
    "_id": "50f5f5d4014e045f000002",
        "author": {
        "name": "Chris Crawford",
        "photo": "http://example.com/photo.jpg"
    },
        "status": "This is a sample message.",
        "comments": [{
        "_id": "5160eacbe4b020ec56a46844",
            "text": "This is the content of the comment.",
            "author": "Bob Hope"
    }, {
        "_id": "5160eacbe4b020ec56a46845",
            "text": "This is the content of the comment.",
            "author": "Bob Hope"
    }]
}, {
    "_id": "50f5f5d4014e045f000003",
        "author": {
        "name": "Brown Robert",
            "photo": "http://example.com/photo.jpg"
    },
        "status": "This is another sample message.",
        "comments": [{
        "_id": "5160eacbe4b020ec56a46846",
            "text": "This is the content of the comment.",
            "author": "Bob Hope"
    }, {
        "_id": "5160eacbe4b020ec56a46847",
            "text": "This is the content of the comment.",
            "author": "Bob Hope"
    }]
}];

// Comment Model
var Comment = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
        text: "",
        author: ""
    }
});

// Comments collection
var Comments = Backbone.Collection.extend({
    model: Comment
});

// Author Model
var Author = Backbone.Model.extend({
    defaults: {
        text: "",
        author: ""
    }
});

// Post Model
var Post = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
        author: "",
        status: ""
    },
    parse: function (resp) {
        // Create a Author model on the Post Model
        this.author = new Author(resp.author || null, {
            parse: true
        });
        // Delete from the response object as the data is
        // alredy available on the  model
        delete resp.author;
        // Create a comments objecton model 
        // that will hold the comments collection
        this.comments = new Comments(resp.comments || null, {
            parse: true
        });
        // Delete from the response object as the data is
        // alredy available on the  model
        delete resp.comments;

        // return the response object 
        return resp;
    }
})
// Posts Collection 
var Posts = Backbone.Collection.extend({
    model: Post
});

var PostsListView = Backbone.View.extend({
    el: "#container",
    renderPostView: function(post) {
        // Create a new postView
        var postView = new PostView({
            model : post
        });
        // Append it to the container
        this.$el.append(postView.el);
        postView.render();
    },
    render: function () {
        var thisView = this;
        // Iterate over each post Model
        _.each(this.collection.models, function (post) {
            // Call the renderPostView method
            thisView.renderPostView(post);
        });
    }
});


var PostView = Backbone.View.extend({
    className: "post",
    template: _.template($("#post-template").html()),
    renderComments: function() {
        var commentsListView = new CommentsListView({
            // Comments collection on the Post Model
            collection : this.model.comments,
            // Pass the container to which it is to be appended
            el : $('.comments', this.$el)
        });
        commentsListView.render();        
    },
    render: function () {
        this.$el.empty();
        //  Extend the object toi contain both Post attributes
        // and also the author attributes
        this.$el.append(this.template(_.extend(this.model.toJSON(),
            this.model.author.toJSON()
       )));
       // Render the comments for each Post
       this.renderComments();
    }
});

var CommentsListView = Backbone.View.extend({
    renderCommentView: function(comment) {
        // Create a new CommentView
        var commentView = new CommentView({
            model : comment
        });
        // Append it to the comments ul that is part
        // of the view
        this.$el.append(commentView.el);
        commentView.render();
    },
    render: function () {
        var thisView = this;
        // Iterate over each Comment Model
        _.each(this.collection.models, function (comment) {
            // Call the renderCommentView method
            thisView.renderCommentView(comment);
        });
    }
});


var CommentView = Backbone.View.extend({
    tagName: "li",
    className: "comment",
    template: _.template($("#comment-template").html()),
    render: function () {
        this.$el.empty();
        this.$el.append(this.template(this.model.toJSON()));
    }
});

// Create a posts collection 
var posts = new Posts(postsObject, {parse: true});

// Pass it to the PostsListView
var postsListView = new PostsListView({
    collection: posts
});
// Render the view
postsListView.render();

更新后,我发现了一个for主干,它提供了模型之间和集合之间的关系。它已被证明是集合内集合以及深层嵌套模型数据的一个很好的解决方案

模型是预定义的,它们通过键与其他模型的关系。在初始化/解析模型的过程中,JSON中该键处的任何值都会传递给新的相关模型或集合。将在两个模型/集合之间创建关系

这意味着在上述示例中,我们可以对模型执行类似操作:

安装程序 用法 不停摆弄

这是一个非常有用的答案,而且对小提琴的演奏有双重帮助。谢谢。谢谢苏珊特。这对像我这样的天真的学习者来说会有很大的帮助。
var postsObject = [{
    "_id": "50f5f5d4014e045f000002",
        "author": {
        "name": "Chris Crawford",
        "photo": "http://example.com/photo.jpg"
    },
        "status": "This is a sample message.",
        "comments": [{
        "_id": "5160eacbe4b020ec56a46844",
            "text": "This is the content of the comment.",
            "author": "Bob Hope"
    }, {
        "_id": "5160eacbe4b020ec56a46845",
            "text": "This is the content of the comment.",
            "author": "Bob Hope"
    }]
}, {
    "_id": "50f5f5d4014e045f000003",
        "author": {
        "name": "Brown Robert",
            "photo": "http://example.com/photo.jpg"
    },
        "status": "This is another sample message.",
        "comments": [{
        "_id": "5160eacbe4b020ec56a46846",
            "text": "This is the content of the comment.",
            "author": "Bob Hope"
    }, {
        "_id": "5160eacbe4b020ec56a46847",
            "text": "This is the content of the comment.",
            "author": "Bob Hope"
    }]
}];

// Comment Model
var Comment = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
        text: "",
        author: ""
    }
});

// Comments collection
var Comments = Backbone.Collection.extend({
    model: Comment
});

// Author Model
var Author = Backbone.Model.extend({
    defaults: {
        text: "",
        author: ""
    }
});

// Post Model
var Post = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
        author: "",
        status: ""
    },
    parse: function (resp) {
        // Create a Author model on the Post Model
        this.author = new Author(resp.author || null, {
            parse: true
        });
        // Delete from the response object as the data is
        // alredy available on the  model
        delete resp.author;
        // Create a comments objecton model 
        // that will hold the comments collection
        this.comments = new Comments(resp.comments || null, {
            parse: true
        });
        // Delete from the response object as the data is
        // alredy available on the  model
        delete resp.comments;

        // return the response object 
        return resp;
    }
})
// Posts Collection 
var Posts = Backbone.Collection.extend({
    model: Post
});

var PostsListView = Backbone.View.extend({
    el: "#container",
    renderPostView: function(post) {
        // Create a new postView
        var postView = new PostView({
            model : post
        });
        // Append it to the container
        this.$el.append(postView.el);
        postView.render();
    },
    render: function () {
        var thisView = this;
        // Iterate over each post Model
        _.each(this.collection.models, function (post) {
            // Call the renderPostView method
            thisView.renderPostView(post);
        });
    }
});


var PostView = Backbone.View.extend({
    className: "post",
    template: _.template($("#post-template").html()),
    renderComments: function() {
        var commentsListView = new CommentsListView({
            // Comments collection on the Post Model
            collection : this.model.comments,
            // Pass the container to which it is to be appended
            el : $('.comments', this.$el)
        });
        commentsListView.render();        
    },
    render: function () {
        this.$el.empty();
        //  Extend the object toi contain both Post attributes
        // and also the author attributes
        this.$el.append(this.template(_.extend(this.model.toJSON(),
            this.model.author.toJSON()
       )));
       // Render the comments for each Post
       this.renderComments();
    }
});

var CommentsListView = Backbone.View.extend({
    renderCommentView: function(comment) {
        // Create a new CommentView
        var commentView = new CommentView({
            model : comment
        });
        // Append it to the comments ul that is part
        // of the view
        this.$el.append(commentView.el);
        commentView.render();
    },
    render: function () {
        var thisView = this;
        // Iterate over each Comment Model
        _.each(this.collection.models, function (comment) {
            // Call the renderCommentView method
            thisView.renderCommentView(comment);
        });
    }
});


var CommentView = Backbone.View.extend({
    tagName: "li",
    className: "comment",
    template: _.template($("#comment-template").html()),
    render: function () {
        this.$el.empty();
        this.$el.append(this.template(this.model.toJSON()));
    }
});

// Create a posts collection 
var posts = new Posts(postsObject, {parse: true});

// Pass it to the PostsListView
var postsListView = new PostsListView({
    collection: posts
});
// Render the view
postsListView.render();
var Author = Supermodel.Model.extend({});
var Post = Supermodel.Model.extend({});
var Comment = Supermodel.Model.extend({});

var Posts = Backbone.Collection.extend({
  model: function(attrs, options) {
    return Post.create(attrs, options);
  }
});
var Comments = Backbone.Collection.extend({
  model: function(attrs, options) {
    return Comment.create(attrs, options);
  }
});

Post.has().one('author', {
  model: Author,
  inverse: 'post'
}).many('comments', {
  collection: Comments,
  inverse: 'post'
});

//reverse relationships could also be setup
var posts = new Posts( postsObject ); //where postsObject is an array of posts

//With SuperModel, we are able to navigate the related models
posts.first().comments();
posts.first().comments().author();
posts.last().author();