【问题标题】:inline conditionals in angular.jsangular.js 中的内联条件
【发布时间】:2012-12-19 07:38:20
【问题描述】:

我想知道除了使用 ng-show 等之外,是否有一种方法可以有条件地显示内容。例如,在骨干网.js 中,我可以对模板中的内联内容做一些事情,例如:

<% if (myVar === "two") { %> show this<% } %>

但在 Angular 中,我似乎仅限于显示和隐藏包含在 html 标签中的内容

<p ng-hide="true">I'm hidden</p>
<p ng-show="true">I'm shown</p>

仅使用 {{}} 而不是将内容包装在 html 标签中,有条件地显示和隐藏 angular 中的内联内容的推荐方法是什么?

【问题讨论】:

  • 如果有机会,请不要接受我的回答并接受 2Toad。

标签: angularjs if-statement ternary-operator


【解决方案1】:

如果我理解你的话,我认为你有两种方法。

首先您可以尝试ngSwitch,第二种可能的方法是创建您自己的filter。可能 ngSwitch 是正确的方法,但如果您想隐藏或显示内联内容,只需使用 {{}} 过滤器即可。

这里是一个fiddle,以一个简单的过滤器为例。

<div ng-app="exapleOfFilter">
  <div ng-controller="Ctrl">
    <input ng-model="greeting" type="greeting">
      <br><br>
      <h1>{{greeting|isHello}}</h1>
  </div>
</div>

angular.module('exapleOfFilter', []).
  filter('isHello', function() {
    return function(input) {
      // conditional you want to apply
      if (input === 'hello') {
        return input;
      }
      return '';
    }
  });

function Ctrl($scope) {
  $scope.greeting = 'hello';
}

【讨论】:

    【解决方案2】:

    有数千种方法可以剥这只猫的皮。我知道您是在专门询问 {{}} 之间的问题,但对于来到这里的其他人,我认为值得展示其他一些选项。

    $scope 上的函数(IMO,在大多数情况下,这是你最好的选择):

      app.controller('MyCtrl', function($scope) {
          $scope.foo = 1;
    
          $scope.showSomething = function(input) {
               return input == 1 ? 'Foo' : 'Bar';
          };
       });
    
     <span>{{showSomething(foo)}}</span>
    

    当然是ng-show和ng-hide:

     <span ng-show="foo == 1">Foo</span><span ng-hide="foo == 1">Bar</span>
    

    ngSwitch

     <div ng-switch on="foo">
       <span ng-switch-when="1">Foo</span>
       <span ng-switch-when="2">Bar</span>
       <span ng-switch-default>What?</span>
     </div>
    

    Bertrand 建议的自定义过滤器。 (如果您必须一遍又一遍地做同样的事情,这是您的最佳选择)

    app.filter('myFilter', function() {
       return function(input) {
         return input == 1 ? 'Foo' : 'Bar';
       }
    }
    
    {{foo | myFilter}}
    

    或者自定义指令:

    app.directive('myDirective', function() {
       return {
         restrict: 'E',
         replace: true,
         link: function(scope, elem, attrs) {
           scope.$watch(attrs.value, function(v) {
              elem.text(v == 1 ? 'Foo': 'Bar');
           });
         }
       };
    });
    
    
    <my-directive value="foo"></my-directive>
    

    就我个人而言,在大多数情况下,我会在我的范围内使用一个函数,它可以使标记保持干净,并且实现起来又快又容易。除非,也就是说,你将一遍又一遍地做同样的事情,在这种情况下,我会按照 Bertrand 的建议,根据具体情况创建一个过滤器或可能的指令。

    与往常一样,最重要的是您的解决方案易于维护,并且希望是可测试的。这将完全取决于您的具体情况。

    【讨论】:

      【解决方案3】:

      编辑:2Toad's answer below 就是你要找的东西!为那件事点赞

      如果您使用的是 Angular

      对此还有一个答案。我发布了一个单独的答案,因为它更像是对解决方案的“精确”尝试,而不是可能的解决方案列表:

      这是一个过滤器,它将执行“立即 if”(又名 iif):

      app.filter('iif', function () {
         return function(input, trueValue, falseValue) {
              return input ? trueValue : falseValue;
         };
      });
      

      并且可以这样使用:

      {{foo == "bar" | iif : "it's true" : "no, it's not"}}
      

      【讨论】:

      • 谢谢你,这就是我想要的。但是我注意到,如果我尝试将 html 标记放在其中一个值中,它会中断:{{thing.second == "two" | iif : "
          " : "
            "}} 我意识到可能有更好的方法可以在角度上做到这一点,但是有没有办法逃避“”以便标签可以作为字符串的一部分输出?
      • ngBind 不允许 HTML 输出,您应该使用 ng-bind-html-unsafe
      • Angular 文档中的 ng-binf-html-unsafe 示例在标签中使用它,例如 。内联可能无法做我想做的事情。
      • IIF 是“Inline If”的缩写。它在不同的编程语言中很常见……只是不如 ?: inline ifs 常见。 ;)
      • @BenLesh 主要支持编辑您的答案,现在还有其他选择,干得好。
      【解决方案4】:

      当无法使用 ng-class 时(例如在设置 SVG 样式时),我正在使用以下有条件地设置类 attr:

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

      同样的方法应该适用于其他属性类型。

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

      我发表了一篇关于使用 AngularJS+SVG 的文章,讨论了这个问题和相关问题。 http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS

      【讨论】:

        【解决方案5】:

        Angular UI 库有内置指令 ui-if 用于模板/视图中的条件,直到 angular ui 1.1.4

        示例: 支持 Angular UI 直到 ui 1.1.4

        <div ui-if="array.length>0"></div>
        

        ng-如果在 1.1.4 之后的所有 Angular 版本中都可用

        <div ng-if="array.length>0"></div>
        

        如果数组变量中有任何数据,那么只会出现 div

        【讨论】:

        • ui-if 至少已从最新版本的 angular-ui 中删除,但从 angular 1.1.5 开始,您拥有 ng-if(来自 this comment
        【解决方案6】:

        我会把我的也加入进来:

        https://gist.github.com/btm1/6802312

        这将评估 if 语句一次并且不添加监视侦听器但是您可以向具有 set-if 称为 wait-for="somedata.prop" 的元素添加一个附加属性,它将等待该数据或属性在评估 if 语句之前设置。如果您正在等待来自 XHR 请求的数据,该附加属性会非常方便。

        angular.module('setIf',[]).directive('setIf',function () {
            return {
              transclude: 'element',
              priority: 1000,
              terminal: true,
              restrict: 'A',
              compile: function (element, attr, linker) {
                return function (scope, iterStartElement, attr) {
                  if(attr.waitFor) {
                    var wait = scope.$watch(attr.waitFor,function(nv,ov){
                      if(nv) {
                        build();
                        wait();
                      }
                    });
                  } else {
                    build();
                  }
        
                  function build() {
                    iterStartElement[0].doNotMove = true;
                    var expression = attr.setIf;
                    var value = scope.$eval(expression);
                    if (value) {
                      linker(scope, function (clone) {
                        iterStartElement.after(clone);
                        clone.removeAttr('set-if');
                        clone.removeAttr('wait-for');
                      });
                    }
                  }
                };
              }
            };
          });
        

        【讨论】:

          【解决方案7】:

          Angular 1.1.5 增加了对三元运算符的支持:

          {{myVar === "two" ? "it's true" : "it's false"}}
          

          【讨论】:

          • 这个投票最多的答案应该出现在答案的顶部......这是迄今为止最正确的
          • user1469779 考虑接受这个答案,因为这是在相当长一段时间内实现您想要的目标的推荐方式
          • @2Toad,我的回答很旧。这是现在正确的答案,我不知道用户现在是否会重新“接受”它,但我已经这样注释了我的答案。这就是软件开发不断变化的面貌。
          • 谢谢。我怎样才能让它显示myVar 的值,只有当它是假的时候? (即如何在表达式中嵌套变量?)我尝试使用{{myVar === "two" ? "it's true" : {{myVar}}}},但它不起作用。
          • @Josh myVar 属性不需要用额外的花括号括起来,它已经在表达式中。试试{{myVar === "two" ? "it's true" : myVar}}
          【解决方案8】:

          要检查变量内容并具有默认文本,您可以使用:

          <span>{{myVar || 'Text'}}</span>
          

          【讨论】:

          • 谢谢!我正在尝试这个,但我错过了字符串周围的引号:-)
          • 无论出于何种原因,这种语法在使用一次性绑定时都不起作用.. {{::myVar || '文本'}} 将不起作用。必须没有 ::
          【解决方案9】:

          即使在异国情调的情况下也能工作:

          <br ng-show="myCondition == true" />
          

          【讨论】:

            【解决方案10】:

            所以使用 Angular 1.5.1(现有的应用程序依赖于其他一些 MEAN 堆栈依赖项是我目前不使用 1.6.4 的原因)

            这对我有用,就像 OP 说的 {{myVar === "two" ? "it's true" : "it's false"}}

            {{vm.StateName === "AA" ? "ALL" : vm.StateName}}
            

            【讨论】:

              【解决方案11】:

              如果你想在值为“0”时显示“None”,你可以这样使用:

              <span> {{ $scope.amount === "0" ?  $scope.amount : "None" }} </span>
              

              在 Angular js 中为真假

              <span> {{ $scope.amount === "0" ?  "False" : "True" }} </span>
              

              【讨论】:

                【解决方案12】:

                最近的角度,我认为是 6+。您有带有 else 条件的 ng-template 连接到标签标识符:

                <div *ngIf="myVar else myVarNo">Yes</div>
                <ng-template #myVarNo><div>No</div></ng-template>
                

                【讨论】:

                  猜你喜欢
                  • 2013-03-24
                  • 2014-07-15
                  • 2012-01-23
                  • 2011-03-08
                  • 2014-11-29
                  • 1970-01-01
                  • 2019-03-01
                  • 2022-01-12
                  • 1970-01-01
                  相关资源
                  最近更新 更多