简体   繁体   中英

how to use ng-show to display specific divs inside an ng-repeat?

I have an ng-repeat div to dynamically display a set of div tags based on a dynamic list of items, that each have a unique Id , a type and a "title" value which are both strings and I have a click function assigned to each of them. When I want to click on one of these divs , I want to display an separate div associated to that clicked div and I want to do that using an ng-show which at the moment has a condition where the id of this item/div should be equal/equivalent to a scope variable I've defined in a controller associated with the html for this new div to be displayed.

The problem I'm getting is that every one of these separate divs is showing and assuming that all the ng-shows are true which shouldn't be the case and I'm not sure why this is happening as all the id's for the items are unique. I've printed out to the console and can't see anything wrong with the assigning of the variable but not sure if I've missed something with regards to the ng-show condition.

Here is what I have so far in html with 2 div examples (don't worry about replicating all the styling, i just want to figure out what is going on with the html/angular stuff):

<div class="col-md-12 col-sm-12 col-xs-12  " ng-repeat="item in items track by item.id"  ng-click="onClick(item.id)">

  //first type div that is clickable
  <div class="row">
    <div>
      <header class="text">
        <h1 data-ng-if="item.title" ng-bind-html="item.title"></h1>
      </header>
    </div>
  </div>

  //div to be displayed after associated first div type is clicked 
  <div class=" col-sm-11 row"  ng-show="displayMessage===item.id"   >
      <header class="col-sm-12 text">
          <h1  data-ng-if="item.title" ng-bind-html="item.title"></h1>
      </header>
      <p class="col-sm-12" > text about {{item.id]} </p>
  </div>

  //2nd type of  div 
  <div class="row"  style=" background: linear-gradient(135deg, #156570, #1e9d8b);">
      <h1 data-ng-if="item.title" ng-bind-html="item.title"></h1>
      <i class="ms-icon ms-icon-heart-rate"></i>
      <div class="clearfix"></div>
  </div>

  //div to be displayed after associated second div is clicked 
  <div class="col-md-11 col-sm-11 col-xs-11"  ng-show="displayMessage===item.id">

    <div style="background: linear-gradient(135deg, #156570, #1e9d8b);"></div>

    <h1 class="col-sm-12 col-xs-12"  data-ng-if="item.title" ng-bind-html="item.title" style="color:#000"></h1>

    <p class="col-sm-12 col-xs-12 "> text associated with {{item.id}}
    </p>

  </div>

</div>

And here is the simple click function I have . $scope.displayMessage is defined earlier on during the controller setup where its set to an empty string:

$scope.onClick = function (itemId) {
    $scope.displayMessage = itemId;
}

Let me know if I need to add more code.

It could be done in a simpler way without adding property to the items varible you have in scope.

Let the Controller be

app.controller('MainCtrl', function($scope) {
  $scope.div_=[]; 

  $scope.items = [
  {
    id: 1,
    title: "first item"
   },
  {
    id: 2,
    title: "second item",
   },
  {
    id: 3,
    title: "third item",
   }
];

  $scope.onClick=function(index,row){
     $scope.div_[index+'_'+row]=true;
   }
  });

HTML will be like

<body ng-controller="MainCtrl">
    <div ng-repeat="item in items">
    <div style="color:red" ng-click="onClick($index,0)">DIV {{$index}}.0---click to show DIV {{$index}}.0_CHILD</div>
    <div style="color:blue" ng-show="div_[$index+'_0']">DIV {{$index}}.0_CLILD</div>
    <br>
    <div style="color:red" ng-click="onClick($index,1)">DIV {{$index}}.1---click to show DIV {{$index}}.1_CHILD</div>
    <div style="color:blue" ng-show="div_[$index+'_1']">DIV {{$index}}.1_CLILD</div>
    <hr>
    </div>
  </body>

Here an array named 'div_' is maintained to trace all ng-show value of all div.

Working plunker https://plnkr.co/edit/uhFdCXkmS4gB95c9bjTR?p=preview

This will be easier for you to accomplish if you had properties on each item to key off of.

For example,

$scope.items = [
  {
    id: 1,
    title: "first item",
    isFirstDivSelected: false,
    isSecondDivSelected: false
   },
  {
    id: 2,
    title: "second item",
    isFirstDivSelected: false,
    isSecondDivSelected: false
   }
  {
    id: 3,
    title: "third item",
    isFirstDivSelected: false,
    isSecondDivSelected: false
   }
];

This will allow you to add an ng-click to your children items.

 <div class="col-md-12 col-sm-12 col-xs-12 " ng-repeat="item in items track by item.id" ng-click="onClick(item.id)"> //first type div that is clickable <div class="row" ng-click="item.isFirstDivSelected = true;"> <div> <header class="text"> <h1 data-ng-if="item.title" ng-bind-html="item.title"></h1> </header> </div> </div> //div to be displayed after associated first div is clicked <div class=" col-sm-11 row" ng-show="item.isFirstDivSelected" > <header class="col-sm-12 text"> <h1 data-ng-if="item.title" ng-bind-html="item.title"></h1> </header> <p class="col-sm-12" > text about {{item.id]} </p> </div> //more divs......... 

Right now, there is no good way to for your application to know that any of your children divs have been clicked. There are other ways you can do this, but in my opinion, adding properties that are well defined and straightforward is the best way.

if you want to show hide rows under loop

<div *ngFor="let client_obj of dashboard_data.data.items ;let i = index"    >
      <input type="checkbox"   [(ngModel)]="div_['level_1_'+i]">
          <div [class.hide]="div_['level_1_'+i]"   >
             {{client_obj.value}}
        </div>
 </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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