Как я могу использовать $ index внутри ng-repeat, чтобы включить класс и показать DIV?

166

У меня есть набор <li>элементов.

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

Когда пользователь нажимает на один из элементов адреса выше, тогда он должен установить значение selected и показать один из <DIV>элементов ниже:

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

Это работает для первых двух случаев.

  • Когда пользователь нажимает ABC, то первый <DIV>показывает 100 и меняет цвет на красный.
  • При нажатии DEF отображается 101, и DEF становится красным.

Однако это не работает вообще для A0, A1, A2 и A3

  • Когда пользователь нажимает A0, A1, A2 или A3, правильное значение не отображается, выбранное значение не устанавливается, и цвет ВСЕХ повторяющихся n0, A1, A2 и A3 становится красным.

Это лучше всего показано, если вы посмотрите на этот Plunker:

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

Обратите внимание, что вверху я добавил {{ selected }}в качестве средства отладки вверху. Кроме того, x in [4,5,6,7]они просто предназначены для имитации цикла. В реальной жизни у меня есть это как ng-repeat="answer in modal.data.answers".

Кто-нибудь знает, как я могу настроить это так, чтобы liток класса был установлен в нужное время и DIVпоказывал в нужное время для A0, A1, A2 и A3 <li>и<DIV>

alan2
источник

Ответы:

201

Проблема здесь заключается в том, что ng-repeatсоздается собственная область действия, поэтому при selected=$indexее создании создается новое selectedсвойство в этой области, а не изменяется существующее. Чтобы это исправить, у вас есть два варианта:

Измените выбранное свойство на не примитивное (т. Е. Объект или массив, который заставляет javascript искать цепочку прототипов), затем установите для него значение:

$scope.selected = {value: 0};

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

Смотреть плункер

или

Используйте $parentпеременную для доступа к правильному свойству. Хотя менее рекомендуется, поскольку это увеличивает связь между областями

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

Смотреть плункер

Ной
источник
2
Это два разных подхода к проблеме. Идея заключалась в том, что вы можете пойти с тем, который вы предпочитаете
Ноя
29

Как уже упоминалось johnnyynnoj ng-repeat создает новую область. Я бы на самом деле использовал функцию для установки значения. Смотреть плункер

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
Есть ли на ng:clickсамом деле работает? Я думал, что это былоng-click
Адам Ф