在 post 中加载评论

Load comments in post

假设我的 Firebase 数据库中有这个结构

已编辑: 我的 JSON 结构如下所示:

{
  ad-comments:{
    48a047b7-28a2-4037-925c-2a809b8d4445:{
      -K4iGKXbniQZUi4r1SW7:{
         Comment:""
         Email:""
         Date:""
         Submitter:""
         ID:""
      }
      -K4hxcKuuxcwuhScPR_v:{...}    
    }
    eeb082e5-59ed-4c3b-8fcd-5af24a2bcada:{...}    
  }
  users:{
    48a047b7-28a2-4037-925c-2a809b8d4445:{
      text:""
      name:""
      email:""
      desc:""
      phone:""
    }
    444198db-1052-4d8d-a1cd-c7e613fbe7c9:{...}  
  }
}

我在控制器中检索用户(每个用户都有一个 属性 post)以使用 $firebaseArray 和 ng-repeat 在视图上显示它们,如下所示:

var ref = new Firebase ("https://url.firebaseio.com/users");
$scope.posts = $firebaseArray("ref");

现在在视图中我只是使用 ng-repeat 来遍历它们

<div ng-repeat="post in posts">

  <div>{{post.name}}</div>
  <div>{{post.text}}</div>

  <div>Comments:<div>
     <div><input type="text" ng-model="comment"></div>
     <div><button ng-click="addComment(post, comment)">Add</button></div>
</div>

所以现在,问题是当它们位于不同的节点时,我如何查询以请求每个 post 的所有评论,我按 ID 存储它们但仍然不知道如何做吧。

在我将评论存储在每个用户内部并且可以显示每个 post 上的评论之前,但是我在安全规则方面遇到了问题,因为我已经指定用户只能修改它自己的内容而不是其他内容,并且将评论留在用户内部不允许其他人发表评论,所以我不得不更改并将评论放在不同的节点中。

你的数据保持平稳,太棒了!

您还在两个位置之间使用共享密钥,这意味着您已经完成了 90%。

有多种方法可以处理这种情况,但 using .$extend() in AngularFire 提供了一个优雅的解决方案。

下面的代码示例使用了 Angular Styleguide,所以如果代码看起来不熟悉,请不要担心。

Here's the full demo on JSBin,下面是创建步骤。

我们想为每个用户加载评论。我们将首先创建一个工厂,通过 uid:

获取 ad-comments
function UserCommentsArray($firebaseArray, rootRef) {
  return function UserCommentsArray(uid) {
    var userCommentsRef = rootRef.child('ad-comments').child(uid);
    return $firebaseArray(userCommentsRef);
  };
}

现在我们将使用 $firebaseArray.$extend() 创建自定义同步数组。

function UsersArray($firebaseArray, rootRef, userCommentsArray) {
    return $firebaseArray.$extend({
      $$added: function(snap) {
        var user = snap.val();
        user.$id = snap.key();
        user.comments = userCommentsArray(snap.key());
        return user;
    }
  });
}

每次将项目添加到数组时,我们都会创建一个用户对象并添加来自 userCommentsArray 的评论。

现在在我们的控制器代码中,我们可以简单地注入 usersArray 并绑定到页面。

function MyCtrl($scope, rootRef, usersArray) {
  var usersRef = rootRef.child('users');
  $scope.users = usersArray(usersRef);
}

在页面上显示此数据需要更改模板:

  <div ng-controller="MyCtrl">

    <div ng-repeat="user in users">

      <div>{{user.name}}</div>

      <ul ng-repeat="comment in user.comments">
        <li>{{ comment.text }}</li>
      </ul>

      <div>Comments:</div>
      <div>
        <input type="text" ng-model="newComment">
      </div>

      <div>
        <button 
          ng-click="addComment(user, newComment)">Add
        </button>
      </div>

    </div>
  </div>

通过查找用户然后在评论数组上调用 $add() 来在用户下方添加评论。

function MyCtrl($scope, rootRef, usersArray) {
  var usersRef = rootRef.child('users');
  $scope.users = usersArray(usersRef);
  $scope.addComment = function (user, newComment) {
    var userRecord = $scope.users.$getRecord(user.$id);
    userRecord.comments.$add({ text: newComment });
  };
}

我不是 Firebase 专家,但我认为您应该考虑如何为 post 及其评论之间的联系建模。 我可以想到两种方法:

  1. Post实体将有一个附加字段:

    列出 commentIds

  2. 评论实体将持有 post

  3. 的 ID

我推荐第一种方法,因为通常我们希望所有者实体(在本例中为 Post 实体)持有其子实体(评论)

现在,当您检索 Post 时,请务必使用评论 ID 检索其所有评论。