Sanotaan, että sinulla on joukko, joka on renderöity ul
-muodossa, jossa on li
jokaiselle elementille ja ohjaimen ominaisuus nimeltä selectedIndex
. Mikä olisi paras tapa lisätä luokka li
:lle, jonka indeksi on selectedIndex
, AngularJS:ssä?
Tällä hetkellä kopioin (käsin) li
-koodin ja lisään luokan yhteen li
-tagista ja käytän ng-show
- ja ng-hide
-ominaisuuksia näyttääkseni vain yhden li
:n per indeksi.
Jos et halua laittaa CSS-luokkien nimiä Controlleriin kuten minä, tässä on vanha temppu, jota olen käyttänyt jo ennen v1-päiviä. Voimme kirjoittaa lausekkeen, joka evaluoi suoraan luokan nimen valittuna, mitään mukautettuja direktiivejä ei tarvita:
ng:class="{true:'selected', false:''}[$index==selectedIndex]"
Huomaa vanha syntaksi kaksoispisteellä.
On myös uusi parempi tapa soveltaa luokkia ehdollisesti, kuten esim:
ng-class="{selected: $index==selectedIndex}"
Angular tukee nyt lausekkeita, jotka palauttavat objektin. Tämän objektin jokaista ominaisuutta (nimeä) pidetään nyt luokan nimenä ja sitä sovelletaan sen arvosta riippuen.
Nämä tavat eivät kuitenkaan ole toiminnallisesti samanarvoisia. Tässä on esimerkki:
ng-class="{admin:'enabled', moderator:'disabled', '':'hidden'}[user.role]"
Voisimme siis käyttää uudelleen olemassa olevia CSS-luokkia periaatteessa liittämällä mallin ominaisuuden luokan nimeen ja samalla pitää CSS-luokat poissa Controller-koodista.
Tässä on paljon yksinkertaisempi ratkaisu:
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>
Kohtasin hiljattain samanlaisen ongelman ja päätin luoda vain ehdollisen suodattimen:
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];
};
});
Se ottaa yhden argumentin, joka on joko 2-elementtinen array tai merkkijono, joka muutetaan arrayksi, johon liitetään tyhjä merkkijono toiseksi elementiksi:
<li ng-repeat="item in products | filter:search | orderBy:orderProp |
page:pageNum:pageLength" ng-class="'opened'|if:isOpen(item)">
...
</li>