Wie kann ich den $ -Index in einer ng-Wiederholung verwenden, um eine Klasse zu aktivieren und einen DIV anzuzeigen?

166

Ich habe eine Reihe von <li>Elementen.

<ul>
  <li ng-class="{current: selected == 100}">
     <a href ng:click="selected=100">ABC</a>
  </li>
  <li ng-class="{current: selected == 101}">
     <a href ng:click="selected=101">DEF</a>
  </li>
  <li ng-class="{current: selected == $index }" 
      ng-repeat="x in [4,5,6,7]">
     <a href ng:click="selected=$index">A{{$index}}</a>
  </li>
</ul>

Wenn ein Benutzer auf eines der oben genannten Adresselemente klickt, sollte er den Wert von selected festlegen und eines der folgenden <DIV>Elemente anzeigen:

<div  ng:show="selected == 100">100</div>
<div  ng:show="selected == 101">101</div>
<div ng-repeat="x in [4,5,6,7]" ng:show="selected == $index">{{ $index }}</div>

Dies funktioniert für die ersten beiden Fälle.

  • Wenn der Benutzer auf ABC klickt, <DIV>zeigt der erste 100 an und ändert die Farbe in Rot.
  • Wenn auf DEF geklickt wird, wird 101 angezeigt und DEF wechselt zu rot.

Es funktioniert jedoch überhaupt nicht für A0, A1, A2 und A3

  • Wenn ein Benutzer auf A0, A1, A2 oder A3 klickt, wird das richtige nicht angezeigt, der ausgewählte Wert wird nicht eingestellt und die Farbe ALLER ng-Wiederholungen A0, A1, A2 und A3 wird rot.

Dies wird am besten gezeigt, wenn Sie sich diesen Plunker ansehen:

http://plnkr.co/edit/7HMeObplaBkx5R0SntjY?p=preview

Beachten Sie, dass ich oben {{ selected }}als Debug-Hilfe oben hinzugefügt habe . Auch die x in [4,5,6,7]sollen nur eine Schleife simulieren. Im wirklichen Leben habe ich das als ng-repeat="answer in modal.data.answers".

Weiß jemand, wie ich das so einstellen kann, dass der liKlassenstrom zur richtigen Zeit und die DIVShows zur richtigen Zeit für die A0, A1, A2 und A3 <li>und eingestellt werden<DIV>

Alan2
quelle

Antworten:

201

Das Problem hierbei ist, dass ng-repeatein eigener Bereich erstellt wird. Wenn Sie dies tun selected=$index, wird eine neue selectedEigenschaft in diesem Bereich erstellt, anstatt die vorhandene zu ändern. Um dies zu beheben, haben Sie zwei Möglichkeiten:

Ändern Sie die ausgewählte Eigenschaft in ein nicht primitives Element (z. B. Objekt oder Array, wodurch Javascript die Prototypenkette nachschlägt) und legen Sie dann einen Wert fest:

$scope.selected = {value: 0};

<a ng-click="selected.value = $index">A{{$index}}</a>

Siehe Plunker

oder

Verwenden Sie die $parentVariable, um auf die richtige Eigenschaft zuzugreifen. Obwohl weniger empfohlen, da es die Kopplung zwischen den Bereichen erhöht

<a ng-click="$parent.selected = $index">A{{$index}}</a>

Siehe Plunker

noj
quelle
2
Es sind zwei getrennte Ansätze für das Problem. Die Idee war, dass Sie mit dem gehen könnten, den Sie bevorzugen.
Noj
29

Wie Johnnyynnoj erwähnte , schafft ng-repeat einen neuen Bereich. Ich würde tatsächlich eine Funktion verwenden, um den Wert einzustellen. Siehe Plunker

JS :

$scope.setSelected = function(selected) {
  $scope.selected = selected;
}

HTML :

{{ selected }}

<ul>
  <li ng-class="{current: selected == 100}">
     <a href ng:click="setSelected(100)">ABC</a>
  </li>
  <li ng-class="{current: selected == 101}">
     <a href ng:click="setSelected(101)">DEF</a>
  </li>
  <li ng-class="{current: selected == $index }" 
      ng-repeat="x in [4,5,6,7]">
     <a href ng:click="setSelected($index)">A{{$index}}</a>
  </li>
</ul>

<div  
  ng:show="selected == 100">
  100        
</div>
<div  
  ng:show="selected == 101">
  101        
</div>
<div ng-repeat="x in [4,5,6,7]" 
  ng:show="selected == $index">
  {{ $index }}        
</div>
Liviu T.
quelle
1
Funktioniert das ng:clickwirklich? Ich dachte es wäreng-click
Adam F