Recimo, da imate polje, ki je prikazano v obliki ul
z li
za vsak element, in lastnost kontrolerja, imenovano selectedIndex
. Kakšen bi bil najboljši način za dodajanje razreda v li
z indeksom selectedIndex
v AngularJS?
Trenutno podvajam (ročno) kodo li
in dodajam razred eni od oznak li
ter uporabljam ng-show
in ng-hide
za prikaz samo enega li
na indeks.
Če ne želite vnesti imen razredov CSS v kontroler, kot to počnem jaz, je tu star trik, ki ga uporabljam že od časov pred 1. Napišemo lahko izraz, ki se ovrednoti neposredno z imenom razreda izbrano, ne potrebujemo nobenih direktiv po meri:
ng:class="{true:'selected', false:''}[$index==selectedIndex]"
Upoštevajte staro sintakso s podpičjem.
Na voljo je tudi nov, boljši način pogojne uporabe razredov, kot npr:
ng-class="{selected: $index==selectedIndex}"
Angular zdaj podpira izraze, ki vračajo objekt. Vsaka lastnost (ime) tega predmeta se zdaj obravnava kot ime razreda in se uporabi glede na njegovo vrednost.
Vendar pa ta načina nista funkcionalno enaka. Tukaj je primer:
ng-class="{admin:'enabled', moderator:'disabled', '':'hidden'}[user.role]"
Zato bi lahko ponovno uporabili obstoječe razrede CSS tako, da bi lastnost modela preslikali v ime razreda, hkrati pa razredov CSS ne bi vključili v kodo krmilnika.
Tukaj je veliko preprostejša rešitev:
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>
Pred kratkim sem se soočil s podobno težavo in se odločil, da ustvarim pogojni filter:
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];
};
});
Sprejema en sam argument, ki je bodisi polje z dvema elementoma bodisi niz, ki se spremeni v polje, ki mu je kot drugi element dodan prazen niz:
<li ng-repeat="item in products | filter:search | orderBy:orderProp |
page:pageNum:pageLength" ng-class="'opened'|if:isOpen(item)">
...
</li>