web-dev-qa-db-ja.com

Ng-ifとng-show/ng-hideの違いは何ですか

ng-ifng-show/ng-hideの違いを理解しようとしていますが、私には同じように見えます。

どちらを使用するかを選択する際に留意すべき違いはありますか?

410

ngIf

ngIfディレクティブ削除または再作成式に基づくDOMツリーの一部。 ngIfに割り当てられた式が偽の値に評価された場合、その要素はDOMから削除され、そうでなければ要素のクローンはDOMに再挿入されます。

<!-- when $scope.myValue is truthy (element is restored) -->
<div ng-if="1"></div>

<!-- when $scope.myValue is falsy (element is removed) -->
<div ng-if="0"></div>

ngIfを使用して要素を削除すると、そのスコープは破棄され、要素が復元されたときに新しいスコープが作成されます。 ngIf内に作成されたスコープは、プロトタイプ継承を使用してその親スコープから継承します。

親スコープで定義されたJavaScriptプリミティブにバインドするためにngModelngIf内で使用されている場合、子スコープ内で変数に行われた変更は、親スコープ内の値には影響しません。

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="data">
</div>        

この状況を回避し、子スコープ内から親スコープ内のモデルを更新するには、オブジェクトを使用します。

<input type="text" ng-model="data.input">
<div ng-if="true">
    <input type="text" ng-model="data.input">
</div>

または、親スコープオブジェクトを参照する$parent変数

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="$parent.data">
</div>

ngShow

ngShowディレクティブ表示または非表示ngShow属性に提供された式に基づいて、指定されたHTML要素ng-hide CSSクラスを要素から削除または追加することで、要素を表示または非表示にします。 .ng-hide CSSクラスはAngularJSで事前定義されており、表示スタイルをnoneに設定します(!importantフラグを使用)。

<!-- when $scope.myValue is truthy (element is visible) -->
<div ng-show="1"></div>

<!-- when $scope.myValue is falsy (element is hidden) -->
<div ng-show="0" class="ng-hide"></div>

ngShow式がfalseと評価されると、ng-hide CSSクラスが要素のclass属性に追加され、それが非表示になります。 trueにすると、ng-hide CSSクラスが要素から削除され、要素が非表示にならないようになります。

508
AlwaysALearner

興味深い点は、両方の優先順位の違いです。

私が言うことができる限り、ng-ifディレクティブはすべてのAngularディレクティブの中で最も高い(そうでないとしても)優先順位の1つを持っています。つまり、優先順位の低い他のすべてのディレクティブよりも先にFIRSTが実行されます。これが最初に実行されるという事実は、事実上、 inner ディレクティブが処理される前に要素が削除されることを意味します。または、少なくともそれが私の考えです。

私は現在の顧客向けに構築しているUIでこれを観察して使用しました。 UI全体が非常に重く詰まっていて、それは至る所にng-showとng-hideを持っていました。あまり詳しく説明しないでくださいが、私は一般的なコンポーネントを作成しました。これはJSON設定を使用して管理できます。そのため、テンプレート内でいくつかの切り替えを行う必要がありました。 ng-repeatが存在し、ng-repeatの中には、たくさんのng-shows、ng-hide、さらにng-switchが存在するテーブルが表示されます。彼らは、リストに少なくとも50回の繰り返しを表示したいと考えていました。私はコードをチェックしました、そして前面のJavaバックエンド+カスタムJSはデータを処理するのに約150msかかり、それからAngularは表示する前にそれを約2-3秒かみました。顧客は文句を言わなかった、しかし私は愕然とした:-)

私の検索で、私はng-ifディレクティブに出会いました。さて、多分それはこのUIを構想する時点で、ng-ifが利用可能ではなかったことを指摘するのが最善です。 ng-showとng-hideにはブール値を返す関数が含まれていたので、それらすべてをng-ifに簡単に置き換えることができました。そうすることによって、すべての内側の指令はもはや評価されないように見えました。それは私が評価されているすべてのディレクティブの約3分の1に戻ることを意味していました、そしてその結果、UIは約500ms - 1秒の読み込み時間をスピードアップしました。 (正確な秒数を判断する方法がありません)

注意してください:指令が評価されていないという事実は、その下で何が起こっているのかについての知識がある推測です。

だから、私の意見では:あなたが要素をページ上に存在させる必要があるなら(すなわち:要素をチェックするために、あるいは何でも)、単に隠すには、ng-show/ng-hideを使う。それ以外の場合は、ng-ifを使用してください。

93
gjoris

ng-ifディレクティブはページからコンテンツを削除し、ng-show/ng-hideはCSSのdisplayプロパティを使用してコンテンツを非表示にします。

これは:first-child:last-child疑似セレクタをスタイルに使いたい場合に便利です。

36
Andrei

@EdSpencerは正しいです。たくさんの要素があり、関連するものだけをインスタンス化するためにng-ifを使うのであれば、リソースを節約できます。 @CodeHaterも、要素を削除して表示することが非常に多い場合は、削除するのではなく非表示にするとパフォーマンスが向上する可能性があるため、やや正確です。

私がng-ifを見つけた主なユースケースは、内容が違法であるなら、それが私が要素をきれいに検証して排除することを可能にするということです。たとえば、nullのイメージ名変数を参照するとエラーが発生しますが、ng-ifしてnullかどうかをチェックすれば、すべて問題ありません。私がng-showをしたならば、エラーはまだ発生するでしょう。

16
wolfdawn

Ng-ifとng-showについて注意すべき重要なことの1つは、フォームコントロールを使用するときはng-ifを使用することをお勧めします。domから要素を完全に削除するためです。

required="true"を使用して入力フィールドを作成し、それを非表示にするようにng-show="false"を設定すると、ユーザーがフォームを送信しようとするとChromeが次のエラーをスローするため、この違いは重要です。

An invalid form control with name='' is not focusable.

入力フィールドという理由が存在し、それはrequiredですが、隠されているのでChromeはそれに焦点を合わせることができません。このエラーはスクリプトの実行を停止させるので、これは文字通りあなたのコードを壊す可能性があります。ので注意してください!

7
supersan

@Gajus Kuizinasと@CodeHaterは正しいです。ここで私はただ例を挙げています。我々がng-ifを使っている間、割り当てられた値がfalseであるならば、全体のhtml要素はDOMから取り除かれるでしょう。割り当てられた値がtrueの場合、html要素はDOMに表示されます。そして範囲は親の範囲と比較して異なります。しかし、ng-showの場合、割り当てられた値に基づいて要素を表示したり隠したりするだけです。しかし、それは常にDOMに残ります。割り当てられた値に従って表示のみが変更されます。

http://plnkr.co/edit/3G0V9ivUzzc8kpLb1OQn?p=preview

この例が範囲を理解するのに役立つことを願っています。 ng-showとng-ifに誤った値を指定して、コンソールでDOMを確認してください。入力ボックスに値を入力して、違いを確認してください。

<!DOCTYPE html>

こんにちはPlunker!

<input type="text" ng-model="data">
<div ng-show="true">
    <br/>ng-show=true :: <br/><input type="text" ng-model="data">
</div>
<div ng-if="true">
    <br/>ng-if=true :: <br/><input type="text" ng-model="data">
</div> 
{{data}}
5
user3982777

事実、そのng-ifディレクティブは、ng-showとは異なり、独自のスコープを作成し、興味深い実用的な違いをもたらします。

angular.module('app', []).controller('ctrl', function($scope){
  $scope.delete = function(array, item){
    array.splice(array.indexOf(item), 1);
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app='app' ng-controller='ctrl'>
   <h4>ng-if:</h4>
   <ul ng-init='arr1 = [1,2,3]'>
      <li ng-repeat='x in arr1'>
        {{show}}
        <button ng-if='!show' ng-click='show=!show'>Delete {{show}}</button>
        <button ng-if='show' ng-click='delete(arr1, x)'>Yes {{show}}</button>
        <button ng-if='show' ng-click='show=!show'>No</button>
      </li>
   </ul>
   
   <h4>ng-show:</h4>
   <ul ng-init='arr2 = [1,2,3]'>
      <li ng-repeat='x in arr2'>
        {{show}}
        <button ng-show='!show' ng-click='show=!show'>Delete {{show}}</button>
        <button ng-show='show' ng-click='delete(arr2, x)'>Yes {{show}}</button>
        <button ng-show='show' ng-click='show=!show'>No</button>
      </li>
   </ul>
   
   <h4>ng-if with $parent:</h4>
    <ul ng-init='arr3 = [1,2,3]'>
      <li ng-repeat='item in arr3'>
        {{show}}
        <button ng-if='!show' ng-click='$parent.show=!$parent.show'>Delete {{$parent.show}}</button>
        <button ng-if='show' ng-click='delete(arr3, x)'>Yes {{$parent.show}}</button>
        <button ng-if='show' ng-click='$parent.show=!$parent.show'>No</button>
      </li>
   </ul>
</div>

最初のリストでは、 innner/own scopeからのon-clickイベント、show変数は変更されていますが、ng-ifは同じ名前の outer scopeからの別の変数を監視しているため、解決策は機能しません。 ng-showの場合、show変数は1つしかないので、それが機能します。最初の試みを修正するために、$parent.showを介して親/外部スコープからshowを参照する必要があります。

2
Slava Utesinov
  1. ng-if falseならDOMから要素を削除します。これはあなたのすべてのイベント、それらの要素に付随するディレクティブが失われることを意味します。たとえば、ng-ifがfalseに評価されると、その要素はDOMから削除され、trueになると再作成されます。

  2. ng-show/ng-hideはDOMから要素を削除しません。これはCSSスタイル(.ng-hide)を使用して要素を表示/非表示にします。このようにして、あなたのイベント、子にアタッチされたディレクティブは失われません。

  3. ng-ifは子スコープを作成しますが、ng-show/ng-hideは作成しません。

1
Amay Kulkarni

ngIf 要素を削除または再作成することによってDOMを操作します。

一方 ngShow は物事を隠す/表示するためにCSSルールを適用します。

ほとんどの場合(常にではありません) 、物事を表示/非表示にするために1回限りのチェックが必要な場合は、ng-ifを使用します。 (チェックボックスをオンにしてテキストボックスを表示、チェックボックスをオフにしてテキストボックスを非表示にするなど)画面を表示してから、ng-showを使用します。

0
curiousBoy

ng-showとng-hideは逆の働きをします。しかし、ng-ifとng-hideまたはng-showの違いは、ng-ifを使用すると要素がドームに作成されますが、ng-hide/ng-show要素を使用すると完全に非表示になることです。

ng-show=true/ng-hide=false:
Element will be displayed

ng-show=false/ng-hide=true:
element will be hidden

ng-if =true
element will be created

ng-if= false
element will be created in the dom. 
0
Prasad Reddy

注意すべきことは、今思いついたことです:ng-showはcssを通してコンテンツを隠します、はい、しかしそれはdivのボタンにあるべきであるという奇妙なグリッチをもたらしました。

私は一番下に2つのボタンを持つカードを持っていました、そして実際の状態に応じて1つは新しいエントリを持つ3番目の、例の編集ボタンと交換されます。 ng-show = falseを使って左側のもの(ファイルの最初にあるもの)を隠すと、次のボタンがカードの外側の右側の境界線になってしまいました。 ng-ifはコードをまったく含まないことでそれを修正します。 (ng-showの代わりにng-ifを使って隠れた驚きがあるかどうかここでチェックしてください)

0
helius