好吧,看来我需要一个提示来指明正确的方向。这个问题分为两部分 - 使用多维 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 Collections和 Backbone.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();
关于javascript - 将 JSON 映射到 backbone.js 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17890439/