javascript - 将 JSON 映射到 backbone.js 集合

标签 javascript json backbone.js backbone.js-collections

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

背景

我有一些 JSON 将从服务器检索并控制它的格式。

多维JSON

我在将模型连接到 JSON 中的部分时遇到了一些问题。假设我只想在下面的示例 JSON 中呈现每篇文章的作者姓名状态 的内容。我在将状态输入到模型中没有问题,但我对如何获取作者姓名有点困惑。根据我的理解,我必须重写解析。

这是糟糕的标准吗/我应该使用更好的 JSON 结构吗?尽可能保持平坦会更好吗?那就是把作者姓名和照片上移一级?

我正在阅读 How to build a Collection/Model from nested JSON with Backbone.js但我还是有点不清楚。

集合中的集合

在 backbone.js 的集合中创建一个集合有什么好的方法吗?我将收集一系列帖子,然后收集对该帖子的评论。当我在 Backbone 中发展时,这甚至可能吗?

据我了解 Backbone.js Collection of CollectionsBackbone.js Collection of Collections Issue , 它看起来像这样吗?

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

{
"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"
                },
                {
                ...
                }
        ]
    },
    {
    ...
    }
]}

我什至感谢任何提示来帮助我。谢谢!

最佳答案

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

我会这样想。

收藏

 Posts
 Comments

模型

 Post
 Comment
 Author

Main collection --  Posts collection
                    (Which contains list of Post Models)

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

第一级 - 属性级别(status,id)。

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

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

集合中的集合 在这里会有点困惑。 正如您在集合中拥有模型(Post Model inside Posts Collection)并且每个模型将再次嵌套一个集合(Comments collection inside Post Model)。基本上你会在模型中处理一个Collection

From my understanding I have to override the parse.

Is this bad standards / is there a better JSON structure I should use?

在 Parse 方法中处理 this 是一个非常合理的解决方案。当您初始化 Collection 或 Model 时,首先调用 Parse 方法,然后调用 initialize 。因此,在 Parse 方法内部处理逻辑是完全合乎逻辑的,而且它一点也不差。

Would it be better to keep it as flat as possible?

我认为将这个平面保持在一个级别不是一个好主意,因为首先在第一级别不需要其他数据。

所以我解决这个问题的方法是在 Post Model 中编写 parse 方法,它处理响应并将 Author 模型和 Comments 集合直接附加到Model 而不是作为 Model 上的一个属性,以保持属性散列干净,由第一级 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();

Check Fiddle

关于javascript - 将 JSON 映射到 backbone.js 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17890439/

相关文章:

javascript - 如何选择非空值输入并隐藏输入并显示另一个输入?

javascript - Jest 中的渲染方法

javascript - 在 JavaScript 中将带小数的 float 解析为 JSON,也将 1 解析为 1.00

javascript - Backbone js 从服务器自动刷新/重新加载集合并使用集合更新 View

javascript - IE8双击表格单元格问题

javascript - div 的内容应始终以大写字母开头并以句号结尾

Python - 将 JSON 键/值转换为键/值,其中值是一个数组

json - 如何将有向无环图 (DAG) 存储为 JSON?

javascript - 打开新窗口,然后滚动到元素

javascript - 从 Backbone.js 中的非 JSON 服务器响应创建模型实例