Come posso usare $ index all'interno di una ng-repeat per abilitare una classe e mostrare un DIV?


166

Ho un insieme di <li>elementi.

<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>

Quando un utente fa clic su uno degli elementi dell'indirizzo sopra, quindi dovrebbe, impostare il valore di selezionato e mostrare uno degli <DIV>elementi di seguito:

<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>

Questo funziona per i primi due casi.

  • Quando l'utente fa clic su ABC, il primo <DIV>mostra 100 e cambia il colore in rosso.
  • Quando si fa clic su DEF, 101 viene visualizzato e DEF diventa rosso.

Tuttavia, non funziona affatto per A0, A1, A2 e A3

  • Quando un utente fa clic su A0, A1, A2 o A3, il valore corretto non viene visualizzato, il valore selezionato non viene impostato e il colore di TUTTA la ripetizione ng A0, A1, A2 e A3 diventa rosso.

Questo è mostrato meglio se guardi questo Plunker:

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

Si noti che in alto ho aggiunto {{ selected }}come aiuto per il debug in alto. Inoltre x in [4,5,6,7]sono pensati solo per simulare un loop. Nella vita reale ho questo come ng-repeat="answer in modal.data.answers".

Qualcuno sa come posso impostare questo in modo che la licorrente della classe sia impostata al momento giusto e gli DIVspettacoli al momento giusto per A0, A1, A2 e A3 <li>e<DIV>

Risposte:


201

Il problema qui è che ng-repeatcrea il proprio ambito, quindi quando lo fai selected=$indexcrea una nuova selectedproprietà in quell'ambito piuttosto che alterare quella esistente. Per risolvere questo problema hai due opzioni:

Cambia la proprietà selezionata in una non primitiva (cioè oggetto o array, che fa cercare javascript nella catena del prototipo) quindi imposta un valore su quello:

$scope.selected = {value: 0};

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

Vedi plunker

o

Utilizzare la $parentvariabile per accedere alla proprietà corretta. Sebbene meno raccomandato in quanto aumenta l'accoppiamento tra ambiti

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

Vedi plunker


2
Sono due approcci separati al problema. L'idea era che potevi scegliere quale preferisci.
noj,

29

Come menzionato da johnnyynnoj ng-repeat crea un nuovo ambito. Vorrei infatti utilizzare una funzione per impostare il valore. Vedi 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>

1
Funziona ng:clickdavvero? Ho pensato che fosseng-click
Adam F
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.