Динамический класс в Angular.js

Я хочу динамически добавить класс css к элементу <li>, который я зацикливаю. Цикл такой:

<li ng-repeat="todo in todos" ng-class="{{todo.priority}}">
  <a href="#/todos/{{todo.id}}">{{todo.title}}</a>
  <p>{{todo.description}}</p>
</li>

В моей модели todo у меня есть приоритет свойства, который может быть «срочным», «не очень важным» или «нормальным», и я просто хочу назначить класс для каждого элемента.

Я знаю, что могу сделать это для логического значения с чем-то вроде ng-class="{'urgent': todo.urgent}" Но моя переменная не является логической, а имеет три значения. Как бы я это сделал? Обратите также внимание, что я не хочу использовать ng-style="...", так как мой класс изменит несколько визуальных вещей.


person mpaepper    schedule 01.02.2013    source источник


Ответы (4)


Вы можете просто назначить функцию как выражение и вернуть оттуда правильный класс. Редактировать: есть лучшее решение для динамических классов. См. примечание ниже.

Фрагмент из просмотра:

<div ng-class="appliedClass(myObj)">...</div>

и в контроллере:

$scope.appliedClass = function(myObj) {
    if (myObj.someValue === "highPriority") {
        return "special-css-class";
    } else {
        return "default-class"; // Or even "", which won't add any additional classes to the element
    }
}

Лучший способ сделать это

Недавно я узнал о другом подходе. Вы передаете объект, свойства которого соответствуют классам, с которыми вы работаете, а значениями являются выражения или логические переменные. Простой пример:

ng-class="{ active: user.id == activeId }"

В этом случае класс active будет добавлен к элементу, если user.id соответствует activeId из объекта $scope!

person ŁukaszBachman    schedule 01.02.2013
comment
Идеально, именно то, что мне было нужно. Спасибо! - person mpaepper; 01.02.2013
comment
Точнее, ng-class принимает либо объект, либо строку, поэтому вы можете сделать ng-class=" 'myClass'+item.priority " - person ProLoser; 21.03.2013
comment
Я угловой нуб, но я думаю, что есть еще одна веская причина использовать последний метод, а не первый - я думаю, что если вы используете функцию, она может не настроить правильные часы, тогда как если вы используете атрибуты напрямую, это должно делать так. - person Ibrahim; 11.09.2013
comment
я уже использовал ваш второй метод, но затем столкнулся со стеной (в основном второй метод не очень полезен, когда у вас есть несколько/сложных способов получения класса, который должен быть размещен.. т.е. материал, который требует больше, чем простой оператор if) .. поэтому +1 к способу 1 - person abbood; 17.07.2014
comment
это очень полезно для меня tech-blog.maddyzone.com/ JavaScript/ - person Rituraj ratan; 06.09.2014
comment
Есть вариант "другой"? Не хочу делать { active: user.id == activeId } {inactive: user.id != activeId}... - person dipi evil; 22.04.2015
comment
@dipievil, зачем тебе еще вариант? Вы просто пишете два правила в CSS, где active перезаписывает другое. Например: a { color: black; } и a.active { color: red; } - person ŁukaszBachman; 24.04.2015
comment
Я знаю, что у меня есть другие способы сделать это. Мне просто интересно. Все-таки танки. ;) - person dipi evil; 24.04.2015
comment
Мне было интересно, возможно ли иметь еще вариант. Я имею в виду, я знаю, что могу написать два правила CSS, но даже зная это, я хочу знать, существует ли опция else :) - person Mauker; 27.05.2015
comment
Насколько я знаю, нет доступной опции else. Это потому, что в CSS вы издеваетесь над этим if-else условием, используя default-overwritten правила. - person ŁukaszBachman; 27.05.2015
comment
@dipievil, ng-class="user.id == activeId ? 'active' : 'inactive'" - person primetwig; 17.09.2015
comment
Это работает только для статического списка известных классов. Если ваши классы на самом деле являются динамическими (в том смысле, что вы не знаете, какой может быть строка класса), вы не можете использовать этот метод. Что раздражает. - person geoidesic; 22.02.2017
comment
@geoidesic, это неправда. Исходное решение ng-class="appliedClass(myObj)" генерирует классы динамически на основе myObj состояния. - person ŁukaszBachman; 30.03.2017

Если вы просто хотите добавить класс, используйте атрибут class с интерполяцией:

class="priority-is-{{todo.priority}}"
person Gilbert    schedule 20.02.2014
comment
Интересно, есть ли у этого недостатки? Это кажется неправильным, но я не знаю, почему. - person Hless; 26.10.2015
comment
вам может понадобиться ng-class, возможно, для хорошей работы IE или Edge - person Erik; 29.02.2016

Почти получилось :)
Должно быть без интерполяционной разметки ({{ и }}):

<li ng-repeat="todo in todos" ng-class="todo.priority">
...
person vucalur    schedule 13.12.2013

Вы можете сделать это динамически и с тернаром.

ng-class="service.Icon != '' ? service.Icon : 'fas fa-arrow-alt-circle-right'"

Приведенный выше код введет класс, хранящийся в Icon, если он не равен нулю, и по умолчанию будет использовать второй, если вы его не включили.

Это позволит использовать несколько классов.

Ответ выше, где вы вызываете функцию () в экземплярах с привязкой к данным, может вызвать цикл потребления документа, если что-либо в состоянии изменится. Если бы вы поместили в это консольную запись, вы могли бы обнаружить, что ваша страница отображается 100 раз, прежде чем она перестанет зацикливаться.

ПРИМЕЧАНИЕ. Не помещайте объект {} вокруг него при использовании троичного кода. Вы получите ошибки.

person Mike Mason    schedule 18.06.2020