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>

1
  • code editor needs ui-bootstrap so here it doesn't work,but this is not related to the question Commented Apr 1, 2016 at 20:20

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

2 Comments

Great!It works perfectly now!I should read about prototypal inheritance a little bit more. Thanks a lot!
@VolodymyrBabak do accept answer. and read up on another linked answer.. Thanks :)
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>

6 Comments

It appears that you haven't initialized the scope variable yet it would not work after intialization due to scoping issue..
It would work but not for the purpose they were trying to achieve which is why I supplied the alternative approach.
"You will probably want to toggle comments per book however."
could you remove 1st half of your answer, which is purely wrong.. if you do that so I can remove downvote..
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".
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.