csdnceshi70
笑故挽风
采纳率14.3%
2011-10-17 10:49 阅读 372

有条件地应用类的最佳方法是什么?

Lets say you have an array that is rendered in a ul with an li for each element and a property on the controller called selectedIndex. What would be the best way to add a class to the li with the index selectedIndex in AngularJS?

I am currently duplicating (by hand) the li code and adding the class to one of the li tags and using ng-show and ng-hide to show only one li per index.

转载于:https://stackoverflow.com/questions/7792652/what-is-the-best-way-to-conditionally-apply-a-class

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

22条回答 默认 最新

  • 已采纳
    weixin_41568127 ?yb? 2011-11-29 11:17

    If you don't want to put CSS class names into Controller like I do, here is an old trick that I use since pre-v1 days. We can write an expression that evaluates directly to a class name selected, no custom directives are necessary:

    ng:class="{true:'selected', false:''}[$index==selectedIndex]"
    

    Please note the old syntax with colon.

    There is also a new better way of applying classes conditionally, like:

    ng-class="{selected: $index==selectedIndex}"
    

    Angular now supports expressions that return an object. Each property (name) of this object is now considered as a class name and is applied depending on its value.

    However these ways are not functionally equal. Here is an example:

    ng-class="{admin:'enabled', moderator:'disabled', '':'hidden'}[user.role]"
    

    We could therefore reuse existing CSS classes by basically mapping a model property to a class name and at the same time keep CSS classes out of Controller code.

    点赞 20 评论 复制链接分享
  • csdnceshi50 三生石@ 2012-08-28 01:13

    ng-class supports an expression that must evaluate to either

    1. A string of space-delimited class names, or
    2. An array of class names, or
    3. A map/object of class names to boolean values.

    So, using form 3) we can simply write

    ng-class="{'selected': $index==selectedIndex}"
    

    See also How do I conditionally apply CSS styles in AngularJS? for a broader answer.


    Update: Angular 1.1.5 has added support for a ternary operator, so if that construct is more familiar to you:

    ng-class="($index==selectedIndex) ? 'selected' : ''"
    
    点赞 30 评论 复制链接分享
  • csdnceshi78 程序go 2013-09-27 13:39

    My favorite method is using the ternary expression.

    ng-class="condition ? 'trueClass' : 'falseClass'"
    

    Note: Incase you're using a older version of Angular you should use this instead,

    ng-class="condition && 'trueClass' || 'falseClass'"
    
    点赞 22 评论 复制链接分享
  • csdnceshi68 local-host 2016-01-14 22:30

    It works properly ;)

    <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>
    
    点赞 10 评论 复制链接分享
  • csdnceshi64 游.程 2015-06-06 10:05

    well i would suggest you to check condition in your controller with a function returning true or false .

    <div class="week-wrap" ng-class="{today: getTodayForHighLight(todayDate, day.date)}">{{day.date}}</div>
    

    and in your controller check the condition

    $scope.getTodayForHighLight = function(today, date){
    return (today == date);
    }
    
    点赞 9 评论 复制链接分享
  • csdnceshi67 bug^君 2011-10-17 13:55

    Here is a much simpler solution:

    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>

    </div>
    
    点赞 8 评论 复制链接分享
  • csdnceshi68 local-host 2012-09-27 02:01

    I'll add to this, because some of these answers seem out of date. Here's how I do it:

    <class="ng-class:isSelected">
    

    Where 'isSelected' is a javascript variable defined within the scoped angular controller.


    To more specifically address your question, here's how you might generate a list with that:

    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": ""}
        ]
    }
    


    See: http://jsfiddle.net/tTfWM/

    See: http://docs.angularjs.org/api/ng.directive:ngClass

    点赞 7 评论 复制链接分享
  • weixin_41568134 MAO-EYE 2013-05-21 12:11

    Here is another option that works well when ng-class can't be used (for example when styling SVG):

    ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"
    

    (I think you need to be on latest unstable Angular to use ng-attr-, I'm currently on 1.1.4)

    点赞 7 评论 复制链接分享
  • csdnceshi62 csdnceshi62 2013-05-23 08:32

    Ternary operator has just been added to angular parser in 1.1.5.

    So the simplest way to do this is now :

    ng:class="($index==selectedIndex)? 'selected' : ''"
    
    点赞 5 评论 复制链接分享
  • csdnceshi64 游.程 2013-07-22 14:25

    If you are using angular pre v1.1.5 (i.e. no ternary operator) and you still want an equivalent way to set a value in both conditions you can do something like this:

    ng-class="{'class1':item.isReadOnly == false, 'class2':item.isReadOnly == true}"
    
    点赞 5 评论 复制链接分享
  • csdnceshi64 游.程 2014-04-03 09:13

    If you having a common class that is applied to many elements you can create a custom directive that will add that class like ng-show/ng-hide.

    This directive will add the class 'active' to the button if it's clicked

    module.directive('ngActive',  ['$animate', function($animate) {
      return function(scope, element, attr) {
        scope.$watch(attr.ngActive, function ngActiveWatchAction(value){
          $animate[value ? 'addClass' : 'removeClass'](element, 'active');
        });
      };
    }]);
    

    More info

    点赞 5 评论 复制链接分享
  • csdnceshi50 三生石@ 2013-07-24 14:57

    I am new to Angular but have found this to solve my issue:

    <i class="icon-download" ng-click="showDetails = ! showDetails" ng-class="{'icon-upload': showDetails}"></i>
    

    This will conditionally apply a class based on a var. It starts off with a icon-download as a default, the using ng-class, I check the status of showDetails if true/false and apply class icon-upload. Its working great.

    Hope it helps.

    点赞 4 评论 复制链接分享
  • weixin_41568208 北城已荒凉 2012-09-04 14:35

    If you want to go beyond binary evaluation and keep your CSS out of your controller you can implement a simple filter that evaluates the input against a map object:

    angular.module('myApp.filters, [])
      .filter('switch', function () { 
          return function (input, map) {
              return map[input] || '';
          }; 
      });
    

    This allows you to write your markup like this:

    <div ng-class="muppets.star|switch:{'Kermit':'green', 'Miss Piggy': 'pink', 'Animal': 'loud'}">
        ...
    </div>
    
    点赞 3 评论 复制链接分享
  • csdnceshi54 hurriedly% 2013-04-09 21:00

    Check http://www.codinginsight.com/angularjs-if-else-statement/

    The infamous angularjs if else statement!!! When I started using Angularjs, I was a bit surprised that I couldn’t find an if/else statement.

    So I was working on a project and I noticed that when using the if/else statement, the condition shows while loading. You can use ng-cloak to fix this.

    <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 }

    Thanks amadou

    点赞 3 评论 复制链接分享
  • csdnceshi68 local-host 2015-11-04 08:55

    We can make a function to manage return class with condition

    enter image description here

    <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>
    

    And then

    <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>
    

    You can refer to full code page at ng-class if example

    点赞 3 评论 复制链接分享
  • csdnceshi56 lrony* 2013-06-09 22:30

    This will probably get downvoted to oblivion, but here is how I used 1.1.5's ternary operators to switch classes depending on whether a row in a table is the first, middle or last -- except if there is only one row in the table:

    <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>
    
    点赞 2 评论 复制链接分享
  • csdnceshi68 local-host 2015-05-03 09:30

    partial

      <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>
    

    controller

      $scope.campaign_range = "all";
      $scope.change_range = function(range) { 
            if (range === "all")
            {
                $scope.campaign_range = "all"
            }
            else
            {  
                $scope.campaign_range = "thismonth"
            }
      };
    
    点赞 2 评论 复制链接分享
  • csdnceshi63 elliott.david 2016-03-16 07:38

    This is in my work multiple conditionally judge:

    <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> &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;
      <span ng-bind-html="eOption.eoName | to_trusted">2020 元</span>
    </li>
    
    点赞 2 评论 复制链接分享
  • csdnceshi51 旧行李 2012-07-26 07:53

    I faced a similar problem recently and decided to just create a conditional 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];
          };
        });
    

    It takes a single argument, which is either a 2-element array or a string, which gets turned into an array that is appended an empty string as the second element:

    <li ng-repeat="item in products | filter:search | orderBy:orderProp |
      page:pageNum:pageLength" ng-class="'opened'|if:isOpen(item)">
      ...
    </li>
    
    点赞 1 评论 复制链接分享
  • csdnceshi70 笑故挽风 2014-05-27 20:07

    The was I recently did that was doing this:

    <input type="password"  placeholder="Enter your password"
    ng-class="{true: 'form-control isActive', false: 'isNotActive'}[isShowing]">
    

    The isShowing value is a value that is located on my controller that gets toggled with the click of a button and the parts between the single parenthesis are classes I created in my css file.

    EDIT: I would also like to add that codeschool.com has a free course that is sponsored by google on AngularJS that goes over all of this stuff and then some. There is no need to pay for anything, just signup for an account and get going! Best of luck to you all!

    点赞 1 评论 复制链接分享
  • csdnceshi76 斗士狗 2014-09-24 20:55

    Just adding something that worked for me today, after much searching...

    <div class="form-group" ng-class="{true: 'has-error'}[ctrl.submitted && myForm.myField.$error.required]">
    

    Hope this assists in your successful development.

    =)

    Undocumented Expression Syntax : Great Website Link... =)

    点赞 1 评论 复制链接分享
  • csdnceshi66 必承其重 | 欲带皇冠 2017-12-05 05:47

    You can use this npm package. It handles everything and has options for static and conditional classes based on a variable or a function.

    // Support for string arguments
    getClassNames('class1', 'class2');
    
    // support for Object
    getClassNames({class1: true, class2 : false});
    
    // support for all type of data
    getClassNames('class1', 'class2', ['class3', 'class4'], { 
        class5 : function() { return false; },
        class6 : function() { return true; }
    });
    
    <div className={getClassNames({class1: true, class2 : false})} />
    
    点赞 评论 复制链接分享

相关推荐