有条件申请课程的最佳方法是什么?


1183

假设您有一个呈现为的数组,ul其中li每个元素都有一个,控制器上有个名为的属性selectedIndexliselectedIndexAngularJS中的索引向类添加类的最佳方法是什么?

我目前正在(手动)复制li代码并将类添加到li标签之一中,并使用ng-showng-hide仅显示li每个索引一个。


2
对这个问题的回答表明,模板的功能远远超过{{varname}}。我在哪里可以找到关于模板的更多文档,例如具有两种不同形式的三元运算符?除了{{varname.fieldname}}之外,docs.angularjs.org / guide / templates似乎没有解释模板在条件等方面的作用。
Christos Hayward 2014年

这是如此的玉米粥有用,我希望它会为你工作tech-blog.maddyzone.com/javascript/...
Rituraj拉坦

Answers:


1384

如果您不想像我一样将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类保留在Controller代码之外。


33
OP,这可能是表达我见过的三元运算符的最差方法。你考虑过了($index==selectedIndex) ? 'selected' : ''吗?
马尔沃里奥(Malvolio)2012年

17
@Malvolio AFAIR,三元运算符未在v0.9.x中的角度表达式内工作。这或多或少是一个开关。
Orcun 2012年

36
ng-class(从2012年1月19日开始)现在支持一个表达式,该表达式必须计算为1)以空格分隔的类名的字符串,或者2)和类名的数组,或者3)类的映射/对象布尔值的名称。因此,使用3):ng-class =“ {selected:$ index == selectedIndex}”
Mark Rajcok 2012年

2
谢谢@Mark,顺便说一句,现在我已经检查过,可以说此方法在v1中有效。在某些情况下它仍然有用。请注意,对象属性名称(键)不一定是true或false,它可以是您想要映射到类名的任何东西。
Orcun 2012年

6
我只想补充一下,我遇到了一个问题,因为我正在使用类似的语法 {classname: '$index === selectedIndex'} ,但是它没有用。当我将所有内容组合在一起并使用==而不是===时,它起作用了。 {classname: '$index==selectedIndex'}
卢卡斯

437

ng-class支持一个表达式,其值必须为

  1. 一串用空格分隔的类名,或者
  2. 类名数组,或者
  3. 类名到布尔值的映射/对象。

因此,使用表格3)我们可以简单地编写

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

另请参阅如何在AngularJS中有条件地应用CSS样式?以获得更广泛的答案。


更新:Angular 1.1.5添加了对三元运算符的支持,因此,如果您对该结构更熟悉:

ng-class="($index==selectedIndex) ? 'selected' : ''"

2
三元运算符+1(现在我需要一个),但1.1。*是“不稳定版本”,在输入时,API如有更改,恕不另行通知。1.0。*是稳定的,因此对于下周推出为期6个月的项目,我会比较满意。
戴夫·埃弗里特

1
ng-class="{'selected': $index==selectedIndex}"为我工作
knuhol 2015年

160

我最喜欢的方法是使用三元表达式。

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

注意:如果您使用的是Angular的旧版本,则应改用它,

ng-class="condition && 'trueClass' || 'falseClass'"

2
这有助于我编写以下表达式:ng-class="property.name=='timestamp' ? 'property-timestamp' : 'property-'+{{$index}}"。无法找出其他任何方式。
dduft

我真的没有发现为什么我的作用域布尔modalFlag不更新-ng-class =“ {'closed':modalFlag,'open':!modalFlag}”我试图根据作用域变量/布尔值添加关闭或打开-如果有人能帮助我,我将非常感激-谢谢。
降落

它是作为1.5版本引入的。github.com/angular/angular.js/commit/...
Mubashir Koul

55

我将对此加以补充,因为其中一些答案似乎已过时。这是我的方法:

<class="ng-class:isSelected">

其中“ isSelected”是在范围角度控制器内定义的javascript变量。


为了更具体地解决您的问题,以下是如何生成带有该列表的列表:

的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


class =“ ng-class:item.isSelected”和ng-class =“ item.isSelected”之间有什么区别
zloctb 2014年

对使用ng-class:classNamevs只是使用感到好奇class="{{className}}"吗?
Roi 2015年

48

这是一个更简单的解决方案:

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>


74
我强烈建议您的控制器保持CSS内容清洁。那是你不想低头的道路。
leviathan

1
类名称属于模板
Casey 2013年

5
在某个时候,jsfiddle可能会错过支付账单的机会,或者选择迁移到另一个域,或者负责人员被公共汽车杀死(另请参见Bus Factor)。因此,我能否请您回答中解释小提琴的作用?这在堆栈溢出时也是规范的。
塞巴斯蒂安·马赫

27

我最近遇到了类似的问题,因此决定只创建一个条件过滤器:

  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];
      };
    });

它接受一个参数,该参数可以是2元素数组或字符串,它变成一个数组,该数组后面附加一个空字符串作为第二个元素:

<li ng-repeat="item in products | filter:search | orderBy:orderProp |
  page:pageNum:pageLength" ng-class="'opened'|if:isOpen(item)">
  ...
</li>

1
我只是为一个示例创建了yesNo()过滤器,该过滤器根据布尔值1 o 0返回类“是”或“否”:filter('yesNo', function() { return function(input) { // info('yesNo('+ input +')'); switch(input){ case '1': return ' yes '; break; default: return ' no '; break; } } });
svassr 2012年

1
ng-class可以将类名的映射/对象处理为布尔值,因此您可以简单地编写以下代码:ng-class =“ {yes:some_boolean_expression,no:some_other_boolean_expression}”例如,ng-class =“ {yes:输入,否:!input}”
马克·拉杰科克

21

如果您不希望进行二进制评估,而将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>

@Joe,您好,有什么想法如何处理空值?如果我在输入中输入null,它将不会映射其类...
dalcam

1
@ user1191559-您可以在地图上添加一个“默认”项,如果“输入”为null,则返回该值。
乔·斯蒂尔2014年

17

我最近做的是这样做的:

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

isShowing值是位于控制器上的一个值,可通过单击按钮进行切换,并且单个括号之间的部分是我在css文件中创建的类。

编辑:我也想补充一点,codeschool.com有一个免费课程,由google在AngularJS上赞助,涵盖了所有这些东西,然后再介绍一些。无需支付任何费用,只需注册一个帐户即可开始使用!祝大家好运!


您能否在此处提供小提琴或更多代码?isShowing那么控制器中是否有数组?
凯尔·佩内尔

我的猜测是一个布尔
米尔科

15

三元运算符刚刚1.1.5中添加到角度解析器中。

因此,最简单的方法是:

ng:class="($index==selectedIndex)? 'selected' : ''"

另外:class="otherClass ng-class:($index==selectedIndex)? 'selected' : '';"
彼得2013年

11

我们可以创建一个函数来管理带有条件的返回类

在此处输入图片说明

<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的完整代码页(例如)


9

我是Angular的新手,但发现此问题可以解决我的问题:

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

这将有条件地应用基于var的类。它以默认情况下的图标下载开始,使用ng-class,我检查showDetailsif 的状态true/false并应用class icon-upload。它的工作很棒。

希望能帮助到你。


9

这就像一个魅力;)

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

5

这可能会被淘汰,但是这是我使用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>

5

这是我在工作中有条件地做出的多个判断:

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

4

当无法使用ng-class时(例如,在设置SVG样式时),这是一个很好的选择:

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

(我认为您需要使用最新的不稳定Angular才能使用ng-attr-,我目前使用的是1.1.4)


4

好吧,我建议您使用返回truefalse的函数检查控制器中的条件。

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

并在控制器中检查情况

$scope.getTodayForHighLight = function(today, date){
return (today == date);
}

4

部分的

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

3

如果您使用的是v1.1.5之前的版本 (即没有三元运算符),并且仍然希望以相同的方式在两种情况下设置值,可以执行以下操作:

ng-class="{'class1':item.isReadOnly == false, 'class2':item.isReadOnly == true}"

3

如果您有一个适用于许多元素的通用类,则可以创建一个自定义指令,该指令将添加该类,例如ng-show / ng-hide。

如果单击该指令,它将在按钮上添加“活动”类

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

更多信息



3

检查一下

臭名昭著的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 }

谢谢阿马杜


0

您可以使用 npm软件包。它处理所有事情,并具有基于变量或函数的静态和条件类的选项。

// 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})} />
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.