简体   繁体   English

嵌套ng-repeat中来自控制器的AngularJS访问元素

[英]AngularJS access element from controller in nested ng-repeat

I am kind of newbie in AngularJS world, and I'm running into a problem I have't been able to solve. 我是AngularJS世界的新手,遇到了一个我无法解决的问题。 I have a nested ng-repeat view, because I have a nested comment system, so I build the view from an object that is like this: 我有一个嵌套的ng-repeat视图,因为我有一个嵌套的注释系统,因此我是从这样的对象构建视图的:

comments: [{
  _id: ObjectId(x),
  parent_id: ObjectId(y),
  text: 'Hello World!',
  author: {
    id: 1,
    name: Jorge
  }
  replies: [{
    _id: ...,
    parent_id: ...
    author: {
      [...]
    }
    replies: [{
      [...]
    }]
  },
  {
    [...]
  }]
}]

So, every comment have a property named hearts which are the number of likes that it has. 因此,每个评论都有一个名为hearts的属性,该属性是它拥有的点赞数。 I have socket.io implemented so this is all running in real-time. 我已经实现了socket.io,所以这都是实时运行的。 In my controller I have a listener for a new like to a comment, the problem is, how I access a specific comment from my controller to update it likes? 在我的控制器中,我有一个侦听器,用于接收新的喜欢评论,问题是,如何从控制器访问特定评论以更新喜欢的评论?

I have tried by generating a dynamic id in the view like this ng-attr-id="{{'hearts_' + comment._id}}" but this is just working for the parents comments, not for the replies, and I don't know why. 我尝试过在视图中生成动态ID,例如ng-attr-id="{{'hearts_' + comment._id}}"但这仅适用于父母的评论,而不适用于回复,我不知道不知道为什么。

I have also tried to generate a function that looks for the comments and updates it, for instance this function: 我还尝试过生成一个查找注释并对其进行更新的函数,例如,以下函数:

    var setNewHearts = function(comments, comment) {
      for (var i = 0; i < comments.length; i++) {
        if ((String(comments[i]._id)) == (String(comment._id))) {
          comments[i].hearts = eventData.comment.hearts;
          return comments;
        } else if (comments[i].replies) {
          setNewHearts(comments[i].replies, eventData.comment);
        } else {
          //$scope.showMoreComments = true;
        }
      }
    }
    console.log(eventData.comment);
    $scope.comments = setNewHearts($scope.comments, eventData.comment);

but with this function my $scope doesn't get updated in real-time, because I don't have the path to do it, I mean for example $scope.comments[2].replies[0].replies[3].replies[1] 但是使用此功能,我的$ scope不会实时更新,因为我没有执行此操作的路径,例如,我的意思是$scope.comments[2].replies[0].replies[3].replies[1]

I hope someone could help me with this because I am going mad! 我希望有人可以帮助我,因为我快疯了! I have read something about directives. 我已经阅读了一些有关指令的内容。 Could this be my solution? 请问这是我的解决方案吗?

Thank you very much. 非常感谢你。

A recursive directive makes the most sense, but Angular causes an infinite loop with recursive directives and it's a bit ugly to workaround. 递归指令最有意义,但是Angular会使用递归指令导致无限循环,解决方法有点难看。 You can use ng-include recursively like this: Live demo (click). 您可以像这样递归地使用ng-include现场演示(单击)。

<div ng-repeat="comment in comments" ng-include="'comment.html'"></div>

<script type="text/ng-template"  id="comment.html">
  <div>
    <p>{{comment.author.name}}: {{comment.text}}</p>
    <div class="reply" ng-repeat="comment in comment.replies" ng-include="'comment.html'"></div>
  </div>
</script>

This is the sample data I used: 这是我使用的示例数据:

  $scope.comments = [
    {
      id: 1,
      text: 'Hello World!',
      author: {
        id: 1,
        name: 'Jorge'
      },
      replies: [
        {
          id: 2,
          text: 'Hey, Jorge!',
          author: {
            id: 2,
            name: 'World'
          },
          replies: [
            {
              id: 3,
              text: 'Woah!',
              author: {
                id: 1,
                name: 'Jorge'
              }
            }
          ]
        }
      ]
    }
  ];

For the updating when the socket message comes in, I would do this: 对于套接字消息传入时的更新,我可以这样做:

socket.on('comment-liked', function(commentId) {
  $scope.$apply(function() {
    // recursively search all objects and return object where `obj.id === commentId`
    var comment = findCommentById($scope.comments, likedCommentId);
    // increment the counter or set to 1 if there were no hearts before
    comment.hearts = comments.hearts ? ++comment.hearts : 1;
  });
});

Here's my function to get an array of matching comments. 这是我获取匹配注释数组的功能。 It uses lodash/underscore flatten , but you could do that manually pretty easily if you want. 它使用lodash / underscore flatten ,但是您可以根据需要手动轻松地完成此操作。 It's best to be using npm modules so you can easily include lodash's flatten without bulking up your code with the whole library =D 最好使用npm模块,这样您就可以轻松地包含lodash的flatten而不用整个库= D来增加代码

function findCommentById(comments, id) {
  return _.flatten(comments.map(function(comment) {
    if (comment.id === id) { return comment; }
    return findCommentById(comment.replies, id);
  }))[0];
}

As you can see in this demo , the comment is updated as you wish. 如您在本演示中所看到的,评论将根据您的意愿进行更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM