Как использовать переменные контроллера вместе с ng-click для переключения класса?

http://plnkr.co/edit/nEfBE33AJen3mz9YvjeC?p=preview

У меня есть список кнопок тегов, по умолчанию после того, как все элементы загружены, я установил первые 3 элемента, чтобы иметь selected учебный класс.

Теперь мне также нужны теги, чтобы получить или потерять selected класс на ng-click,

Как бы вы совместили код в разметке или контроллере?

.controller('PageCtrl',
    ['$scope',
    function($scope) {

    var vs = $scope;
    vs.message = "1st, 2nd and 3rd item should be selected by default:";

    // Gives the 1st 3 items the selected class
    vs.toggleTags = { item: [0, 1, 2] };

    // the ng-click to individually toggle the selected class:
    vs.selectTag = function(term) {
        alert(term +' in tag #'+ vs.toggleTags.item);
    };

    vs.tags = [
      {name: 'aaa'},
      {name: 'bbb'},
      {name: 'ccc'},
      {name: 'ddd'},
      {name: 'eee'},
      {name: 'fff'},
      {name: 'ggg'}
    ];

}]);

HTML

<ul>
    <li ng-repeat="(k, m) in tags"
        ng-class="{'selected':toggleTags.item.indexOf(k) > -1}"
        ng-click="toggleTags.item = $index; selectTag(m.name)">
        <div class="tag">{{m.name}}</div>
    </li>
</ul>

В основном я хотел бы объединить что-то вроде: {'selected' : toggle.state} в ng-class линия. Прямо сейчас мой код отменяет выбор всего.

Есть идеи?

4 ответа

Решение

Если вы не хотите изменять данные, которые вы получаете с сервера - вы можете создать модель выбора отдельно:

<li ng-repeat="(k, m) in tags"
          ng-class="{'selected':selectedModel[$index]}"
          ng-click="selectedModel[$index] = !selectedModel[$index]">

http://plnkr.co/edit/QpoAs9XFknKug8mpNkkO?p=preview

Конечно, лучше использовать идентификаторы, а не индексы, если они есть.

Вы можете добиться этого, обновив функцию контроллера следующим образом:

 vs.selectTag = function(term,k) {
  if(vs.toggleTags.item.indexOf(k) == -1){
    vs.toggleTags.item.push(k)
  }
  else {
    vs.toggleTags.item.splice(vs.toggleTags.item.indexOf(k),1);
  }
    alert(term +' in tag #'+ vs.toggleTags.item);
};

И обновите HTML до:

<li ng-repeat="(k, m) in tags"
    ng-class="{'selected':toggleTags.item.indexOf(k) > -1}"
    ng-click="selectTag(m.name,k)">
    <div class="tag">{{m.name}}</div>
</li>

http://plnkr.co/edit/bqXi4GHxJjbD03ilJ4Me?p=preview

Новый plnkr (для переключения): http://plnkr.co/edit/bqXi4GHxJjbD03ilJ4Me?p=preview

Вы можете сделать что-то вроде этого. Используя дополнительную переменную внутри вашего tags

vs.tags = [
  {name: 'aaa', active: true},
  {name: 'bbb', active: true},
  {name: 'ccc', active: true},
  {name: 'ddd', active: false},
  {name: 'eee', active: false},
  {name: 'fff', active: false},
  {name: 'ggg', active: false}
];

Каждая кнопка имеет объект, поэтому вместо использования другого массива, чтобы проверить, отмечена ли кнопка, вы можете добавить его к существующему объекту (m объект в вашем коде).

Таким образом, вы можете сделать {'selected': m.state} что довольно чисто.

Как показал maddog, вам просто нужно добавить активное свойство к объекту тегов и проверить там, если оно выбрано, а не в другом массиве, для этого нет никаких причин (по крайней мере, один из них, который вы нам показали).

Другие вопросы по тегам