2

I try to create a list of books which may or may not contain comments. So I'd like to have ability to click on comments link (if it contains comments) and to see a list of comments.

I've read that each <li> creates its own scope. So I've tried to create local variable and show/hide comments list depending on click of "comments" link.

For some reason ng-click doesn't work and doesn't change "showComments" variables

I wrote small example to describe problem.

Any suggestions? Thanks.

 var app = angular.module('myApp', ['ui.bootstrap']);

app.controller('bookCtrl', function($scope) {

   $scope.books=[
    {Name:"Book1",Comments:["first comment book1,second comment book1"]},
    {Name:"Book2",Comments:["first comment book2,second comment book2"]},
    {Name:"Book3",Comments:[]}
   ];
});
html, body {
    width: 100%;
    height: 100%;
}

ul{
  list-style-type:none;
}

a:hover {
 cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-controller="booksCtrl">
  <ul>
    <li ng-repeat="book in books">
      <div class="row">
        {{book.Name}}
      </div>
      <div>
        <a ng-if="book.Comments.length>0" ng-click="showComments = !showComments ">Comments</a>
      </div>
      <div ng-show="showComments">
        <ul>
          <li ng-repeat="comment in book.Comments">
            {{comment}}
          </li>
        </ul>
      </div>
    </li>
  </ul>
</div>
Mr Lister
  • 45,515
  • 15
  • 108
  • 150

2 Answers2

1

showComment inside ng-repeat is different than the outer showComment variable. Because ng-repeat does create a child scope on each iteration, while rendering a DOM. That scope is always prototypically inherited from it parent scope. You could read about Prototypal inheritance in this answer.

Do have showComment property on each, as it will also make more sense to view individual book comment

Markup

<div ng-controller="booksCtrl">
  <ul>
    <li ng-repeat="book in books">
      <div class="row">
        {{book.Name}}
      </div>
      <div>
        <a ng-if="book.Comments.length>0" ng-click="book.showComments= !book.showComments">
           Comments
        </a>
      </div>
      <div ng-show="book.showComments">
        <ul>
          <li ng-repeat="comment in book.Comments">
            {{comment}}
          </li>
        </ul>
      </div>
    </li>
  </ul>
</div>

Similar answer here

Community
  • 1
  • 1
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
0

You will probably want to toggle comments per book however. So you could do this..

Controller

app.controller('bookCtrl', function($scope) {

   $scope.books=[
    {Name:"Book1",Comments:["first comment book1,second comment book1"], showComments: false},
    {Name:"Book2",Comments:["first comment book2,second comment book2"], showComments: false},
    {Name:"Book3",Comments:[], showComments: false}
   ];

Html

<a ng-if="book.Comments.length" ng-click="book.showComments= !book.showComments ">Comments</a>
..
<div ng-show="book.showComments">
   <ul>
       <li ng-repeat="comment in book.Comments">
          {{comment}}
       </li>
    </ul>
</div>
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
Fintan Kearney
  • 743
  • 7
  • 15
  • *It appears that you haven't initialized the scope variable yet* it would not work after intialization due to scoping issue.. – Pankaj Parkar Apr 01 '16 at 20:29
  • It would work but not for the purpose they were trying to achieve which is why I supplied the alternative approach. – Fintan Kearney Apr 01 '16 at 20:32
  • "You will probably want to toggle comments per book however." – Fintan Kearney Apr 01 '16 at 20:36
  • could you remove 1st half of your answer, which is purely wrong.. if you do that so I can remove downvote.. – Pankaj Parkar Apr 01 '16 at 20:37
  • I understand your opinion but I believe my answer was sufficient. The first half of the answer is in response to "For some reason ng-click doesn't work and doesn't change "showComments" variables". – Fintan Kearney Apr 01 '16 at 20:39
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/107995/discussion-between-pankaj-parkar-and-fintan-kearney). – Pankaj Parkar Apr 01 '16 at 20:40