angular.jsのインライン条件文


192

ng-showなどを使用する以外に、条件付きでコンテンツを表示する方法があるかどうか疑問に思っていました。たとえば、backbone.jsで、次のようなテンプレートのインラインコンテンツで何かを行うことができます。

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

しかし、角度では、htmlタグで囲まれたものの表示と非表示に制限されているようです

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

コンテンツをhtmlタグでラップするのではなく、{{}}を使用するだけで角度付きでインラインコンテンツを条件付きで表示および非表示にする推奨の方法は何ですか?


6
機会があったら、私の答えを受け入れずに2Toadを受け入れてください。
Ben Lesh 14

回答:


139

編集: 以下の2Toadの答えはあなたが探しているものです!そのことを賛成

Angular <= 1.1.4を使用している場合、この答えは次のようになります:

これに対するもう1つの答え。別の回答を投稿します。これは、可能な解決策のリストではなく、解決策に対する「正確な」試みの方が多いためです。

これは、「即時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タグを値の1つに入れようとすると、壊れてしまうことに気づきました。{{thing.second == "two" | iif: "<ul class = 'two-class'>": "<ul>"}}これを角度で行うにはもっと良い方法があるかもしれませんが、 "<"と ">"をエスケープする方法はありますタグを文字列の一部として出力できるようにするには?
user1469779 2013年

1
ngBindはHTML出力を許可しないため、ng-bind-html-unsafe
Ben Lesh

角度付きドキュメントのng-binf-html-unsafeの例では、<ANY ng-bind-html-unsafe = "{expression}">などのタグ内で使用しています。インラインで実行しようとしていることを実行できない場合があります。
user1469779 2013年

1
IIFは "Inline If"の略です。これは、さまざまなプログラミング言語で一般的です...インラインの場合ほど一般的ではありません。;)
Ben Lesh 2013

18
@BenLeshの主要な小道具はあなたの答えを編集するためのものです。
Nick Coad

724

Angular 1.1.5は三項演算子のサポートを追加しました:

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

14
最も多くの賛成票を持つこの回答は、回答の一番上に表示されるはずです...間違いなく最も正確です
コード

3
user1469779は、この答えを受け入れることを検討してください。これは、しばらくの間、あなたが望むものを達成するための推奨される方法であるためです
Filip Kis

13
@ 2Toad、私の答えは古いものでした。これが正しい答えです。ユーザーが今すぐ「受け入れる」かどうかはわかりませんが、自分の答えに注釈を付けました。これが、ソフトウェア開発の変化する側面です。
Ben Lesh 14

2
ありがとう。myVarfalseの場合にのみの値を表示するにはどうすればよいですか?(つまり、式に変数をネストするにはどうすればよいですか?)試してみました{{myVar === "two" ? "it's true" : {{myVar}}}}が、機能しません。
Josh

6
@Josh myVarプロパティは、追加の波括弧で囲む必要はありません。すでに式の中にあります。試してみる{{myVar === "two" ? "it's true" : myVar}}
2Toad

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をスタイリングする場合)、次のようにして条件付きでクラスattrを設定します。

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

同じアプローチが他の属性タイプでも機能するはずです。

(ng-attr-を使用するには、最新の不安定なAngularを使用する必要があると思います。現在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

何らかの理由で、この構文は1回限りのバインディングでは機能しません。{{:: myVar || 'Text'}}は機能しません。::なしである必要があります
aoakeson

3

私があなたのことをよく理解していれば、それには2つの方法があると思います。

最初にngSwitchを試すことができ、2番目に可能な方法は独自のフィルターを作成することです。おそらく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-ifは1.1.4以降のすべての角度バージョンで利用可能

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

配列変数にデータがある場合、divのみが表示されます


ui-if少なくとも最新バージョンのangular-uiから削除されましたが、angular 1.1.5以降ng-ifこのコメントから)
Dave Everitt 2013年

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>

または角度jsの真偽

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

1

エキゾチックな状況でも機能します:

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

0

私はミックスで私を投げます:

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

これはifステートメントを1回評価し、監視リスナーを追加しませんが、set-ifがwait-for = "somedata.prop"と呼ばれる要素に属性を追加すると、そのデータまたはプロパティが設定されるまで待機します。 ifステートメントを1回評価します。この追加の属性は、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');
              });
            }
          }
        };
      }
    };
  });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.