将JSON映射到backbone.js集合

Sir*_*sen 7 javascript json backbone.js backbone.js-collections

好吧,看起来我需要一个提示,指出我正确的方向.这个问题分为两部分 - 使用JSON的多维JSON和集合集合.

背景

我有一些JSON将从服务器检索并控制如何格式化.

多维JSON

我在将模型连接到JSON中的部件时遇到了一些麻烦.假设我想要呈现每个帖子的作者姓名,以及下面示例JSON中的状态内容.我对模型中的状态没有任何问题,但作者名称我对如何获得它有点困惑.根据我的理解,我必须覆盖解析.

这是不好的标准/我应该使用更好的JSON结构吗?保持尽可能平坦会更好吗?那是将作者姓名和照片提升一级吗?

我正在阅读如何使用Backbone.js从嵌套的JSON构建集合/模型,但对我来说仍然有点不清楚.

集合中的集合

有没有一种很好的方法在backbone.js的集合中创建一个集合?我将收集一些帖子,然后会在该帖子上收集评论.因为我在骨干方面的发展甚至可能吗?

根据我在Backbone.js集合集合和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 })
Run Code Online (Sandbox Code Playgroud)

示例JSON

{
"posts" : [
    {
        "_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" : "Chris Crawford",
            "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"
                },
                {
                ...
                }
        ]
    },
    {
    ...
    }
]}
Run Code Online (Sandbox Code Playgroud)

我甚至欣赏任何提示给我的提示.谢谢!

Sus*_* -- 13

在尝试编写代码以使其适用于嵌套对象时,这可能会让人不知所措.但是为了简化它,可以将它分解成更小的可管理部分.

我想在这些方面.

集合

 Posts
 Comments
Run Code Online (Sandbox Code Playgroud)

楷模

 Post
 Comment
 Author
Run Code Online (Sandbox Code Playgroud)
Main collection --  Posts collection
                    (Which contains list of Post Models)
Run Code Online (Sandbox Code Playgroud)

并且each model in the Posts collection将具有3组属性(可能不是正确的术语).

第一级属性(status,id).

2nd - 作者属性,可以放在单独的模型(Authod模型)中.

第3版 - 每个帖子模型的评论集合.

集合中的集合在这里会有点混乱.就像你在Collection(Post Model inside Posts Collection)中使用Models一样,每个Model都会再次嵌套一个集合(Comments collection inside Post Model).基本上你会处理一个Collection inside a Model.

根据我的理解,我必须覆盖解析.

这是不好的标准/我应该使用更好的JSON结构吗?

在Parse方法中处理此处理是一个非常合理的解决方案.初始化Collection或Model时,首先调用Parse方法,然后调用initialize.因此,处理Parse方法中的逻辑是完全合乎逻辑的,并且它根本不是一个糟糕的标准.

保持尽可能平坦会更好吗?

我不认为将这个单元保持在一个单一级别是一个好主意,因为首先不需要在第一级别上的其他数据.

因此,我处理这个问题的parse方法是编写Post Model处理响应的方法,并将作者模型和评论集合直接附加在模型上,而不是作为模型上的属性,以保持属性散列清理由第1级的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();
Run Code Online (Sandbox Code Playgroud)

检查小提琴


Sir*_*sen 0

更新,我找到了一个主干超级模型,它提供了模型之间和集合之间的关系。事实证明,它是集合中集合以及深度嵌套模型数据的绝佳解决方案。

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

这意味着通过上面的例子,我们可以对我们的模型做这样的事情:

设置

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
Run Code Online (Sandbox Code Playgroud)

用法

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();
Run Code Online (Sandbox Code Playgroud)

小提琴

JSFiddle 中的工作示例