angular.js中的内联条件


192

我想知道是否有一种方法可以使用ng-show等方法来有条件地显示内容,例如在骨干.js中,我可以对模板中的内联内容执行以下操作:

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

但在角度上,我似乎仅限于显示和隐藏包装在html标签中的东西

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

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


6
如果有机会,请不要接受我的回答,请接受2Toad。
Ben Lesh 2014年

Answers:


139

编辑:2Toad下面的答案是您正在寻找!支持那个东西

如果您使用的是Angular <= 1.1.4,那么此答案将有效:

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

这是一个过滤器,可以执行“立即如果”(也称为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:“ <ul class ='two-class'>”:“ <ul>”}}}我意识到也许有更好的方法可以用角度进行此操作,但是有一种方法可以转义“ <”和“>”以便标签可以作为字符串的一部分输出?
user1469779 2013年

1
ngBind不允许HTML输出,您需要使用ng-bind-html-unsafe
Ben Lesh

Angular文档中的ng-binf-html-unsafe示例在标记中使用它,例如<ANY ng-bind-html-unsafe =“ {expression}”>。可能无法做我要内联的事情。
user1469779 2013年

1
IIF是“ Inline If”的缩写。它在不同的编程语言中很常见...只是不如?:内联ifs常见。;)
Ben Lesh 2013年

18
@BenLesh用于编辑答案的主要道具,现在还有其他选择,很好的工作。
尼克·科德

724

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

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

14
投票最多的答案应该出现在答案的最上方……这是迄今为止最正确的答案
Code Whisperer

3
user1469779考虑接受此答案,因为这是一段时间以来实现所需目标的推荐方法
Filip Kis 2014年

13
@ 2Toad,我的回答很旧。现在这是正确的答案,我不知道用户是否现在会回到“接受”状态,但是我已经对答案做了注释。这就是软件开发不断变化的面貌。
Ben Lesh 2014年

2
谢谢。myVar仅当它为false时,如何显示它的值?(即,如何在表达式中嵌套变量?)我尝试过,{{myVar === "two" ? "it's true" : {{myVar}}}}但是不起作用。
2014年

6
@Josh myVar属性不需要用大括号括起来,它已经在表达式内。试试{{myVar === "two" ? "it's true" : myVar}}
2Toad 2014年

60

数以千计的方式给这只猫剥皮。我知道您是在{{}}之间询问,但是对于其他来这里的人,我认为值得展示其他一些选择。

在$ 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的建议并创建一个过滤器或一个指令。

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


18

当无法使用ng-class时(例如,在设置SVG样式时),我使用以下条件来有条件地设置class 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


15

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

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

1
谢谢!我正在尝试此操作,但是我想念字符串中的引号:-)
Simona Adriani 2015年

无论出于何种原因,这种语法都不能使用一次绑定。.{{:: myVar || '文本'}}将不起作用。必须没有:: ::
aoakeson

3

如果我对您的了解很好,我想您有两种方法可以做到。

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

这是一个带有简单过滤器的小提琴作为示例。

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

3

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

示例:在UI 1.1.4之前的Angular UI中支持

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

ng-如果在1.1.4之后的所有角度版本中均可用

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

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


ui-if至少已从最新版本的angular-ui中删除,但自从angular 1.1.5起ng-if(您已从此评论中删除)
Dave Everitt

2

因此,使用Angular 1.5.1 (我对其他MEAN堆栈依赖项具有现有的应用程序依赖关系就是为什么我目前未使用1.6.4的原因)

这对我来说就像OP所说的那样 {{myVar === "two" ? "it's true" : "it's false"}}

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

2

如果要在值为“ 0”时显示“无”,则可以用作:

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

或在angular js中为true false

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


0

我将我的加入:

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');
              });
            }
          }
        };
      }
    };
  });
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.