【问题标题】:Ternary operator in AngularJS templatesAngularJS 模板中的三元运算符
【发布时间】:2012-08-14 01:36:06
【问题描述】:

你如何用 AngularJS(在模板中)做一个三元组?

在 html 中使用一些属性(类和样式)而不是创建和调用控制器的函数会很好。

【问题讨论】:

    标签: javascript html angularjs ternary-operator


    【解决方案1】:

    此答案早于 1.1.5 版本,其中 $parse 函数中的适当三元组不可用。如果您使用的是较低版本或作为过滤器示例,请使用此答案:

    angular.module('myApp.filters', [])
      
      .filter('conditional', function() {
        return function(condition, ifTrue, ifFalse) {
          return condition ? ifTrue : ifFalse;
        };
      });
    

    然后把它当作

    <i ng-class="checked | conditional:'icon-check':'icon-check-empty'"></i>
    

    【讨论】:

    • 我为三元运算符提出了这个问题,但最后我使用了一个过滤器,感觉非常好...... =D
    【解决方案2】:
      <body ng-app="app">
      <button type="button" ng-click="showme==true ? !showme :showme;message='Cancel Quiz'"  class="btn btn-default">{{showme==true ? 'Cancel Quiz': 'Take a Quiz'}}</button>
        <div ng-show="showme" class="panel panel-primary col-sm-4" style="margin-left:250px;">
          <div class="panel-heading">Take Quiz</div>
          <div class="form-group col-sm-8 form-inline" style="margin-top: 30px;margin-bottom: 30px;">
    
            <button type="button" class="btn btn-default">Start Quiz</button>
          </div>
        </div>
      </body>
    

    按钮切换和更改按钮标题以及显示/隐藏 div 面板。见Plunkr

    【讨论】:

      【解决方案3】:

      更新: Angular 1.1.5 添加了三元运算符,此答案仅对 1.1.5 之前的版本正确。对于 1.1.5 及更高版本,请参阅当前接受的答案。

      Angular 1.1.5 之前:

      angularjs中三元的形式为:

      ((condition) && (answer if true) || (answer if false))
      

      一个例子是:

      <ul class="nav">
          <li>
              <a   href="#/page1" style="{{$location.path()=='/page2' && 'color:#fff;' || 'color:#000;'}}">Goals</a>
          </li>
          <li>
              <a   href="#/page2" style="{{$location.path()=='/page2' && 'color:#fff;' || 'color:#000;'}}">Groups</a>
          </li>
      </ul>
      

      或:

       <li  ng-disabled="currentPage == 0" ng-click="currentPage=0"  class="{{(currentPage == 0) && 'disabled' || ''}}"><a> << </a></li>
      

      【讨论】:

      • 很奇怪。这不是很直观。我想知道为什么它是这样实现的。
      • 从未实现过三元,但这只是使用二元运算符的工作方式。
      • @blesh,AngularJS 提升了可测试性。模板不应包含任何逻辑。模板中的三元运算符应重构为对控制器的函数调用,以获得更好的可测试性。
      • @arg20 你应该使用ngClass 指令(或ngClassEven 和ngClassOdd)。然后将选择css类的所有逻辑都放在控制器中。这更容易自动测试。
      • @arg20 我说把它放在控制器里,而不是放在模型里。这应该不是问题。但是,文档说:“评估的结果可以是表示空格分隔的类名的字符串、数组或类名到布尔值的映射”。这意味着您可以使用 "{ cssclass: someBoolCheck() }" 作为表达式,即将 css 类放在视图中,并将逻辑放在控制器中。以this jsFiddle 为例。
      【解决方案4】:

      对于角模板中的文本(userType 是 $scope 的属性,如 $scope.userType):

      <span>
        {{userType=='admin' ? 'Edit' : 'Show'}}
      </span>
      

      【讨论】:

        【解决方案5】:

        更新:Angular 1.1.5 添加了ternary operator,所以现在我们可以简单地写了

        <li ng-class="$first ? 'firstRow' : 'nonFirstRow'">
        

        如果您使用的是早期版本的 Angular,您的两个选择是:

        1. (condition &amp;&amp; result_if_true || !condition &amp;&amp; result_if_false)
        2. {true: 'result_if_true', false: 'result_if_false'}[condition]

        上面的项目 2. 创建了一个具有两个属性的对象。数组语法用于选择名称为 true 的属性或名称为 false 的属性,并返回相关值。

        例如,

        <li class="{{{true: 'myClass1 myClass2', false: ''}[$first]}}">...</li>
         or
        <li ng-class="{true: 'myClass1 myClass2', false: ''}[$first]">...</li>
        

        $first 在第一个元素的 ng-repeat 中设置为 true,因此上面将仅在第一次通过循环时应用类 'myClass1' 和 'myClass2'。

        使用 ng-class 有一个更简单的方法:ng-class 接受一个表达式,该表达式必须计算为以下之一:

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

        上面给出了 1) 的示例。以下是 3 的示例,我认为它读起来更好:

         <li ng-class="{myClass: $first, anotherClass: $index == 2}">...</li>
        

        第一次通过 ng-repeat 循环,添加了 myClass 类。第三次通过($index 从 0 开始),添加类 anotherClass。

        ng-style 接受一个表达式,该表达式必须计算为 CSS 样式名称到 CSS 值的映射/对象。例如,

         <li ng-style="{true: {color: 'red'}, false: {}}[$first]">...</li>
        

        【讨论】:

        • 如果可以的话,我会再次投票支持您更新问题!
        • 我会处理的,@Narretz。
        • 在对象键访问示例中,您可以跳过“假”键,因为它无论如何都是空字符串。
        • 警告,1.1.5 目前不稳定。
        • 如果更新模型时条件发生变化怎么办?我想更新ng-style,但它似乎只在第一次渲染元素时才被评估。 (这里是角菜鸟)
        【解决方案6】:

        虽然您可以在旧版本的 Angular 中使用 condition &amp;&amp; if-true-part || if-false-part-syntax,但通常的三元运算符 condition ? true-part : false-partAngular 1.1.5 and later 中可用。

        【讨论】:

          【解决方案7】:

          就是这样:在 1.1.5 中将三元运算符添加到角度解析器中! see the changelog

          Here is a fiddle 显示在 ng-class 指令中使用的新三元运算符。

          ng-class="boolForTernary ? 'blue' : 'red'"
          

          【讨论】: