如何使用Firebase和AngularJS创建评论线程?



我使用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。

希望这对你有帮助!

最新更新