La oss si at du har en matrise som gjengis i en ul
med en li
for hvert element og en egenskap på kontrolleren som heter selectedIndex
. Hva ville være den beste måten å legge til en klasse til li
med indeksen selectedIndex
i AngularJS?
Jeg dupliserer for øyeblikket (for hånd) li
-koden og legger til klassen i en av li
-kodene og bruker ng-show
og ng-hide
for å vise bare en li
per indeks.
Hvis du ikke ønsker å sette CSS-klassenavn i Controller som jeg gjør, her er et gammelt triks som jeg bruker siden pre-v1 dager. Vi kan skrive et uttrykk som evaluerer direkte til et klassenavn valgt , ingen tilpassede direktiver er nødvendige:
ng:class="{true:'selected', false:''}[$index==selectedIndex]"
*Legg merke til den gamle syntaksen med kolon.
Det finnes også en ny og bedre måte å bruke klasser betinget på, som:
ng-class="{selected: $index==selectedIndex}"
Angular støtter nå uttrykk som returnerer et objekt. Hver egenskap (navn) til dette objektet betraktes nå som et klassenavn og brukes avhengig av verdien.
Disse måtene er imidlertid ikke funksjonelt like. Her er et eksempel:
ng-class="{admin:'enabled', moderator:'disabled', '':'hidden'}[user.role]"
Vi kan derfor gjenbruke eksisterende CSS-klasser ved i utgangspunktet å tilordne en modellegenskap til et klassenavn og samtidig holde CSS-klasser utenfor kontrollerkoden.
Her er en mye enklere løsning:
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>
Jeg møtte et lignende problem nylig og bestemte meg for å bare lage et betinget 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];
};
});
Det tar et enkelt argument, som enten er en 2-element matrise eller en streng, som blir omgjort til en matrise som er lagt til en tom streng som det andre elementet:
<li ng-repeat="item in products | filter:search | orderBy:orderProp |
page:pageNum:pageLength" ng-class="'opened'|if:isOpen(item)">
...
</li>