Каков наилучший способ условного применения класса?
Допустим, у вас есть массив, который отображается в ul
с li
для каждого элемента и свойство на контроллере с именем selectedIndex
. Что было бы лучшим способом добавить класс в li
с индексом selectedIndex
в AngularJS?
В настоящее время я дублирую (вручную) код li
и добавляю класс к одному из тегов li
и используя ng-show
и ng-hide
, чтобы показать только один li
для каждого индекса.
Ответы
Ответ 1
Если вы не хотите помещать имена классов CSS в Controller, как я, это старый трюк, который я использую с пре-v1 дней. Мы можем написать выражение, которое оценивается непосредственно в выбранном имени класса, никакие настраиваемые директивы не нужны:
ng:class="{true:'selected', false:''}[$index==selectedIndex]"
Обратите внимание на старый синтаксис с двоеточием.
Существует также новый лучший способ применения классов условно, например:
ng-class="{selected: $index==selectedIndex}"
Angular теперь поддерживает выражения, возвращающие объект. Каждое свойство (имя) этого объекта теперь рассматривается как имя класса и применяется в зависимости от его значения.
Однако эти способы не являются функционально равными. Вот пример:
ng-class="{admin:'enabled', moderator:'disabled', '':'hidden'}[user.role]"
Поэтому мы могли бы повторно использовать существующие классы CSS, в основном сопоставляя свойство модели с именем класса и одновременно сохраняя классы CSS из кода контроллера.
Ответ 2
ng-class поддерживает выражение, которое должно оцениваться как
- Строка имен классов, разделенных пробелами, или
- Массив имен классов или
- Карта/объект имен классов для булевых значений.
Итак, используя форму 3), мы можем просто написать
ng-class="{'selected': $index==selectedIndex}"
См. также Как условно применить стили CSS в AngularJS? для более широкого ответа.
Обновление: Angular 1.1.5 добавила поддержку тернарный оператор, поэтому, если эта конструкция более знакомы вам:
ng-class="($index==selectedIndex) ? 'selected' : ''"
Ответ 3
Мой любимый метод использует тернарное выражение.
ng-class="condition ? 'trueClass' : 'falseClass'"
Примечание: Если вы используете более старую версию Angular, вы должны использовать это вместо этого,
ng-class="condition && 'trueClass' || 'falseClass'"
Ответ 4
Я добавлю к этому, потому что некоторые из этих ответов кажутся устаревшими. Вот как я это делаю:
<class="ng-class:isSelected">
Где 'isSelected' - это переменная javascript, определенная в контроллере angular.
Чтобы более конкретно рассмотреть ваш вопрос, вот как вы можете сгенерировать список с этим:
HTML
<div ng-controller="ListCtrl">
<li class="ng-class:item.isSelected" ng-repeat="item in list">
{{item.name}}
</li>
</div>
JS
function ListCtrl($scope) {
$scope.list = [
{"name": "Item 1", "isSelected": "active"},
{"name": "Item 2", "isSelected": ""}
]
}
См.: http://jsfiddle.net/tTfWM/
Смотрите: http://docs.angularjs.org/api/ng.directive:ngClass
Ответ 5
Вот гораздо более простое решение:
function MyControl($scope){
$scope.values = ["a","b","c","d","e","f"];
$scope.selectedIndex = -1;
$scope.toggleSelect = function(ind){
if( ind === $scope.selectedIndex ){
$scope.selectedIndex = -1;
} else{
$scope.selectedIndex = ind;
}
}
$scope.getClass = function(ind){
if( ind === $scope.selectedIndex ){
return "selected";
} else{
return "";
}
}
$scope.getButtonLabel = function(ind){
if( ind === $scope.selectedIndex ){
return "Deselect";
} else{
return "Select";
}
}
}
.selected {
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<div ng-app ng-controller="MyControl">
<ul>
<li ng-class="getClass($index)" ng-repeat="value in values" >{{value}} <button ng-click="toggleSelect($index)">{{getButtonLabel($index)}}</button></li>
</ul>
<p>Selected: {{selectedIndex}}</p>
</div>
Ответ 6
Недавно я столкнулся с подобной проблемой и решил создать условный фильтр:
angular.module('myFilters', []).
/**
* "if" filter
* Simple filter useful for conditionally applying CSS classes and decouple
* view from controller
*/
filter('if', function() {
return function(input, value) {
if (typeof(input) === 'string') {
input = [input, ''];
}
return value? input[0] : input[1];
};
});
Требуется один аргумент, который представляет собой либо двухэлементный массив, либо строку, которая превращается в массив, который добавляет пустую строку в качестве второго элемента:
<li ng-repeat="item in products | filter:search | orderBy:orderProp |
page:pageNum:pageLength" ng-class="'opened'|if:isOpen(item)">
...
</li>
Ответ 7
Если вы хотите выйти за рамки двоичной оценки и оставить свой CSS вне своего контроллера, вы можете реализовать простой фильтр, который оценивает входные данные против объекта карты:
angular.module('myApp.filters, [])
.filter('switch', function () {
return function (input, map) {
return map[input] || '';
};
});
Это позволяет вам писать свою разметку следующим образом:
<div ng-class="muppets.star|switch:{'Kermit':'green', 'Miss Piggy': 'pink', 'Animal': 'loud'}">
...
</div>
Ответ 8
Тернарный оператор
Ответ 9
Недавно я сделал это:
<input type="password" placeholder="Enter your password"
ng-class="{true: 'form-control isActive', false: 'isNotActive'}[isShowing]">
Значение isShowing
- это значение, которое находится на моем контроллере, которое переключается одним нажатием кнопки, а части между единственной скобкой - это классы, которые я создал в моем файле css.
EDIT: Я также хотел бы добавить, что у кодовchool.com есть бесплатный курс, который спонсируется google на AngularJS, который охватывает все это, а затем и некоторые. Нет необходимости платить за что-либо, просто зарегистрируйтесь для учетной записи и уходите!
Удачи вам всем!
Ответ 10
Мы можем создать функцию для управления возвращаемым классом с условием
<script>
angular.module('myapp', [])
.controller('ExampleController', ['$scope', function ($scope) {
$scope.MyColors = ['It is Red', 'It is Yellow', 'It is Blue', 'It is Green', 'It is Gray'];
$scope.getClass = function (strValue) {
switch(strValue) {
case "It is Red":return "Red";break;
case "It is Yellow":return "Yellow";break;
case "It is Blue":return "Blue";break;
case "It is Green":return "Green";break;
case "It is Gray":return "Gray";break;
}
}
}]);
</script>
И затем
<body ng-app="myapp" ng-controller="ExampleController">
<h2>AngularJS ng-class if example</h2>
<ul >
<li ng-repeat="icolor in MyColors" >
<p ng-class="[getClass(icolor), 'b']">{{icolor}}</p>
</li>
</ul>
<hr/>
<p>Other way using : ng-class="{'class1' : expression1, 'class2' : expression2,'class3':expression2,...}"</p>
<ul>
<li ng-repeat="icolor in MyColors">
<p ng-class="{'Red':icolor=='It is Red','Yellow':icolor=='It is Yellow','Blue':icolor=='It is Blue','Green':icolor=='It is Green','Gray':icolor=='It is Gray'}" class="b">{{icolor}}</p>
</li>
</ul>
Вы можете ссылаться на полную страницу кода ng-class, если пример
Ответ 11
Я новичок в Angular, но нашел это, чтобы решить мою проблему:
<i class="icon-download" ng-click="showDetails = ! showDetails" ng-class="{'icon-upload': showDetails}"></i>
Это условно применит класс, основанный на var.
Он начинается с icon-download по умолчанию, используя ng-класс, я проверяю статус showDetails
, если true/false
и применяю класс icon-upload, Он отлично работает.
Надеюсь, что это поможет.
Ответ 12
Он работает правильно;)
<ul class="nav nav-pills" ng-init="selectedType = 'return'">
<li role="presentation" ng-class="{'active':selectedType === 'return'}"
ng-click="selectedType = 'return'"><a href="#return">return
</a></li>
<li role="presentation" ng-class="{'active':selectedType === 'oneway'}"
ng-click="selectedType = 'oneway'"><a href="#oneway">oneway
</a></li>
</ul>
Ответ 13
Это, вероятно, будет уменьшено до забвения, но вот как я использовал 1.1.5 тройных операторов для переключения классов в зависимости от того, является ли строка в таблице первой, средней или последней - за исключением случаев, когда в одной строке есть только одна строка таблица:
<span class="attribute-row" ng-class="(restaurant.Attributes.length === 1) || ($first ? 'attribute-first-row': false || $middle ? 'attribute-middle-row': false || $last ? 'attribute-last-row': false)">
</span>
Ответ 14
частичная
<div class="col-md-4 text-right">
<a ng-class="campaign_range === 'thismonth' ? 'btn btn-blue' : 'btn btn-link'" href="#" ng-click='change_range("thismonth")'>This Month</a>
<a ng-class="campaign_range === 'all' ? 'btn btn-blue' : 'btn btn-link'" href="#" ng-click='change_range("all")'>All Time</a>
</div>
контроллер
$scope.campaign_range = "all";
$scope.change_range = function(range) {
if (range === "all")
{
$scope.campaign_range = "all"
}
else
{
$scope.campaign_range = "thismonth"
}
};
Ответ 15
Вот еще один вариант, который хорошо работает, когда ng-класс не может использоваться (например, при стилизации SVG):
ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"
(Я думаю, вам нужно быть на последнем неустойчивом Angular, чтобы использовать ng-attr-, я в настоящее время на 1.1.4)
Ответ 16
Ну, я бы предложил вам проверить условие в вашем контроллере с функцией, возвращающей true или false.
<div class="week-wrap" ng-class="{today: getTodayForHighLight(todayDate, day.date)}">{{day.date}}</div>
и в вашем контроллере проверьте состояние
$scope.getTodayForHighLight = function(today, date){
return (today == date);
}
Ответ 17
Это в моей работе несколько условно судить:
<li ng-repeat='eOption in exam.examOptions' ng-class="exam.examTitle.ANSWER_COM==exam.examTitle.RIGHT_ANSWER?(eOption.eoSequence==exam.examTitle.ANSWER_COM?'right':''):eOption.eoSequence==exam.examTitle.ANSWER_COM?'wrong':eOption.eoSequence==exam.examTitle.RIGHT_ANSWER?'right':''">
<strong>{{eOption.eoSequence}}</strong> |
<span ng-bind-html="eOption.eoName | to_trusted">2020 元</span>
</li>
Ответ 18
Проверка
http://www.codinginsight.com/angularjs-if-else-statement/
Позорное выражение angularjs if else!!! Когда я начал использовать Angularjs, я был немного удивлен, что я не смог найти оператор if/else.
Итак, я работал над проектом, и я заметил, что при использовании инструкции if/else условие отображается во время загрузки.
Вы можете использовать ng-cloak, чтобы исправить это.
<div class="ng-cloak">
<p ng-show="statement">Show this line</span>
<p ng-hide="statement">Show this line instead</span>
</div>
.ng-cloak { display: none }
Спасибо amadou
Ответ 19
Если вы используете angular pre v1.1.5 (т.е. не тернарный оператор), и вы все равно хотите получить эквивалентный способ установить значение в условиях, вы можете сделайте что-нибудь вроде этого:
ng-class="{'class1':item.isReadOnly == false, 'class2':item.isReadOnly == true}"
Ответ 20
Если у вас есть общий класс, который применяется ко многим элементам, вы можете создать настраиваемую директиву, которая добавит этот класс, например ng-show/ng-hide.
Эта директива добавит класс 'active' к кнопке, если она нажала
module.directive('ngActive', ['$animate', function($animate) {
return function(scope, element, attr) {
scope.$watch(attr.ngActive, function ngActiveWatchAction(value){
$animate[value ? 'addClass' : 'removeClass'](element, 'active');
});
};
}]);
Дополнительная информация
Ответ 21
Просто добавив что-то, что сработало для меня сегодня, после долгих поисков...
<div class="form-group" ng-class="{true: 'has-error'}[ctrl.submitted && myForm.myField.$error.required]">
Надеюсь, что это поможет в вашем успешном развитии.
=)
Недокументированное выражение Синтаксис: Отличная ссылка на сайт... =)