我使用AngularJS和Firebase创建了一个Reddit克隆。我正在工作,允许张贴评论评论(评论线程)。Firebase不喜欢使用嵌套数组,它更喜欢扁平结构。我发现这个使用Firebase创建嵌套注释的例子,但它使用jQuery,我真的不清楚如何"翻译"。
我如何去创建"嵌套"(线程)注释,而不实际使用嵌套数组?
这是我的评论控制器(称为PostViewCtrl):
'use strict';
app.controller('PostViewCtrl', function ($scope, $routeParams, Post, Auth) {
$scope.user = Auth.user;
$scope.signedIn = Auth.signedIn;
$scope.post = Post.get($routeParams.postId);
$scope.comments = Post.comments($routeParams.postId);
$scope.addComment = function () {
if(!$scope.commentText || $scope.commentText === '') {
return;
}
var comment = {
text: $scope.commentText,
creator: $scope.user.profile.username,
creatorUID: $scope.user.uid
};
$scope.comments.$add(comment);
$scope.commentText = '';
};
$scope.deleteComment = function (comment) {
$scope.comments.$remove(comment);
};
});
这是我的Post服务(与Firebase通信):
'use strict';
app.factory('Post', function ($firebase, FIREBASE_URL) {
var ref = new Firebase(FIREBASE_URL);
var posts = $firebase(ref.child('posts')).$asArray();
var Post = {
all: posts,
create: function (post) {
return posts.$add(post).then(function(postRef) {
$firebase(ref.child('user_posts').child(post.creatorUID))
.$push(postRef.name());
return postRef;
});
},
get: function (postId) {
return $firebase(ref.child('posts').child(postId)).$asObject();
},
delete: function (post) {
return posts.$remove(post);
},
comments: function (postId) {
return $firebase(ref.child('comments').child(postId)).$asArray();
}
};
return Post;
});
DOM和注释线程都是树数据结构。HTML是为支持树而构建的,但是将它们存储在数据库中是一个常见的问题。解决这个问题的一个方法是使用邻接表。
在这个列表中,每个资源,或者在本例中是注释,将存储一个与它嵌套的注释的id
相同的parent_id
,从而创建一个"扁平"数据结构。
重要的是要承认Firebase使用Mongo,这是一个分层数据库,因此可以"嵌套"数据;但是,创建者不建议这样做,所以让我们坚持使用"平面"方法。
假设我们现在有了一个"平面"数据结构,我们仍然需要将其转换为一个嵌套的数据结构,以便它可以很好地呈现给DOM。下面是一个如何在JavaScript中从平面数据结构构建树的示例,下面是一个具有相同效果的库。
最后,一旦你有了你的嵌套注释,或者一个注释线程,我建议你遵循这篇博客文章,在angular中构建一个嵌套的递归指令,把它渲染到DOM。
希望这对你有帮助!