71

私はこのような角度のテンプレートを持っています...

<div ng-repeat="message in data.messages" ng-class="message.type">

    <div class="info">
        <div class="type"></div>
        <div class="from">From Avatar</div>
        <div class="createdBy">Created By Avatar</div>
        <div class="arrowTo">
            <div class="arrow"></div>
            <div class="to">To Avatar</div>
        </div>
        <div class="date">
            <div class="day">25</div>
            <div class="month">Dec</div>
        </div>
    </div>

    <div class="main">
        <div class="content">
            <div class="heading2">{{message.title}}</div>
            <div ng-bind-html="message.content"></div>
        </div>

    </div>

    <br />
    <hr />
    <br />

</div>

バインドされているデータを表示するように JSfiddleを設定しました。

私がする必要があるのは、データの内容に応じて、「from」、「to」、「arrowTo」の div を条件付きで表示することです。

ログはこれです...

  • データに「from」オブジェクトがある場合は、「from」div を表示してデータをバインドしますが、「createdBy」div は表示しません。
  • 「from」オブジェクトがなく、「createdBy」オブジェクトがある場合は、「createdBy」div を表示してデータをバインドします。
  • データに「to」オブジェクトがある場合は、「arrowTo」div を表示し、そのデータをバインドします。

または平易な英語で、from アドレスがある場合はそれを表示し、そうでない場合は代わりに誰がレコードを作成したかを表示し、to アドレスがある場合はそれも表示します。

私は ng-switch の使用を検討しましたが、データがない場合は空の div を残す余分なマークアップを追加する必要があると思います。さらに、スイッチ ディレクティブをネストする必要がありますが、それが機能するかどうかはわかりません。

何か案は?

アップデート:

私が独自のディレクティブを作成する場合 (方法を知っていれば!)、それをどのように使用したいかを示す擬似コードを次に示します...

<div ng-if="showFrom()">
    From Template Goes Here
</div>
<div ng-if="showCreatedBy()">
    CreatedBy Template Goes Here
</div>
<div ng-if="showTo()">
    To Template Goes Here
</div>

関数/式が false と評価されると、これらはそれぞれ消えます。

4

3 に答える 3

89

Angular 1.1.5では、ng-ifディレクティブが導入されました。これが、この特定の問題に対する最善の解決策です。古いバージョンのAngularを使用している場合は、angular-uiのui-ifディレクティブの使用を検討してください。

「テンプレートの条件付きロジック」の一般的な質問に対する回答を探してここに到着した場合は、次のことも考慮してください。


元の答え:

これはそれほど優れていない「ng-if」ディレクティブです。

myApp.directive('ngIf', function() {
    return {
        link: function(scope, element, attrs) {
            if(scope.$eval(attrs.ngIf)) {
                // remove '<div ng-if...></div>'
                element.replaceWith(element.children())
            } else {
                element.replaceWith(' ')
            }
        }
    }
});

これにより、このHTML構文が可能になります。

<div ng-repeat="message in data.messages" ng-class="message.type">
   <hr>
   <div ng-if="showFrom(message)">
       <div>From: {{message.from.name}}</div>
   </div>    
   <div ng-if="showCreatedBy(message)">
      <div>Created by: {{message.createdBy.name}}</div>
   </div>    
   <div ng-if="showTo(message)">
      <div>To: {{message.to.name}}</div>
   </div>    
</div>

フィドル

replaceWith()は、不要なコンテンツをDOMから削除するために使用されます。

また、Google +で述べたように、カスタムディレクティブの代わりにng-showを使用する場合は、ng-styleを使用して背景画像を条件付きで読み込むことができます。(他の読者の利益のために、JonはGoogle+で次のように述べています。「どちらの方法も、display:noneを使用し、DOMに余分なマークアップを残すため、避けようとしているng-showを使用します。これは、このシナリオでは特に問題です。非表示の要素には、ほとんどのブラウザに引​​き続き読み込まれる背景画像が含まれます。」)。 AngularJSでCSSスタイルを条件付きで適用するにはどうすればよいですか?
も参照してください。

angle -ui ui-ifディレクティブは、if条件/式への変更を監視します。私のはしません。したがって、私の単純な実装では、テンプレート出力にのみ影響するようにモデルが変更された場合にビューが正しく更新されますが、条件/式の回答が変更された場合はビューが正しく更新されません。

たとえば、モデル内でfrom.nameの値が変更されると、ビューが更新されます。ただし、の場合delete $scope.data.messages[0].from、from名はビューから削除されますが、if-condition / expressionが監視されていないため、テンプレートはビューから削除されません。

于 2012-12-29T22:34:06.040 に答える
21

ngSwitchディレクティブを使用できます。

  <div ng-switch on="selection" >
    <div ng-switch-when="settings">Settings Div</div>
    <span ng-switch-when="home">Home Span</span>
    <span ng-switch-default>default</span>
  </div>

空の div で DOM をロードしたくない場合は、$http を使用してカスタム ディレクティブを作成し、(サブ) テンプレートをロードし、特定の条件に達したときに $compile を使用して DOM に挿入する必要があります。

これは単なる (テストされていない) 例です。最適化できますし、最適化する必要があります。

HTML:

<conditional-template ng-model="element" template-url1="path/to/partial1" template-url2="path/to/partial2"></div>

指令:

app.directive('conditionalTemplate', function($http, $compile) {
   return {
      restrict: 'E',
      require: '^ngModel',
      link: function(sope, element, attrs, ctrl) {
        // get template with $http
        // check model via ctrl.$viewValue
        // compile with $compile
        // replace element with element.replaceWith()
      }
   };
});
于 2012-12-29T10:51:22.503 に答える
6

ループ内のすべての div 要素で ng-show を使用できます。これはあなたが望んでいたものですか: http://jsfiddle.net/pGwRu/2/ ?

<div class="from" ng-show="message.from">From: {{message.from.name}}</div>
于 2012-12-29T00:42:08.357 に答える