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


回答:


521

ngIf

ngIfディレクティブ削除したり再作成式に基づいてDOMツリーの部分を。ngIf評価に割り当てられた式がfalse値に評価される場合、要素は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スコープは、プロトタイプ継承を使用して親スコープから継承します。

ngModel内で使用しngIfて、親スコープで定義されたJavaScriptプリミティブにバインドする場合、子スコープ内の変数に加えられた変更は、親スコープの値に影響しません。たとえば、

<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ディレクティブ表示または非表示に提供される発現に基づいて、指定されたHTML要素ngShowの属性。要素は、ng-hideCSSクラスを要素から削除または追加することによって表示または非表示になります。.ng-hideCSSクラスは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-hideCSSクラスが追加されるclass原因となる要素の属性には、隠されたになるために。の場合trueng-hideCSSクラスが要素から削除され、要素が非表示に表示されなくなります。


31
ヒント:ng-ifで追加されたモデルでHTML要素自体を削除すると、ng-modelもう存在しなくなります。
mrzmyr 2014年

3
@CodeHater大きなdomがあったページでng-show / ng-hideよりもng-ifをうまく活用しました。それはページより速く感じるように見えたが、決して科学的分析ではない。
Ed Spencer

私が完全に理解するのに苦労しているのは、モデルdata.inputにオブジェクトがある場合、どのように/なぜそれが機能するかです...しかしdata、モデルの中で単独では機能しません。@CodeHater
Mark Pieszak-Trilon.io

7
@mcpDESIGNS ngIfは新しいスコープを作成するので、ネストされた上記の例を見ると、同じ名前のモデルが親スコープに存在していてもngModel、新しいdataモデルが作成されます。ただし、ドット表記を使用すると、JSにスコープのプロトタイプチェーンを検索させます。したがって、現在のスコープで値が見つからない場合は、親スコープなどで値を探します。別のスコープを作成し、いくつかの他のディレクティブがありngIncludengRepeat。それが今明確であることを願っています。:)
AlwaysALearner

3
どちらがパフォーマンスに優れていますか?ng-showとng-hideだと思いませんか?
tom10271 2015

97

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

私の知る限り、ng-ifディレクティブはすべてのAngularディレクティブの中で最も高い(最も高くないにしても)優先順位の1つです。つまり、他のすべての優先順位の低いディレクティブよりも先に最初に実行されます。最初に実行されるという事実は、要素が内部ディレクティブが処理される前に効果的に削除されることを意味します。または少なくとも:それは私がそれを作るものです。

私はこれを観察し、現在の顧客のために作成しているUIでこれを使用しました。UI全体はかなり重く詰め込まれ、その上にng-showとng-hideがありました。詳細には触れませんが、JSON構成を使用して管理できる汎用コンポーネントを作成したため、テンプレート内でいくつかの切り替えを行う必要がありました。ng-repeatが存在し、ng-repeat内には、ng-shows、ng-hides、さらにはng-switchsが多数存在するテーブルが表示されます。彼らは少なくとも50回の繰り返しをリストに表示したかったので、1500〜2000の指令が解決されることになります。コードを確認したところ、Javaバックエンド+前面のカスタムJSがデータを処理するのに約150ミリ秒かかり、Angularが表示するまでに2〜3秒かかりました。顧客は文句を言わなかったが、私はぞっとさせられた:-)

私の検索では、ng-ifディレクティブを偶然見つけました。さて、このUIを考案した時点では、利用可能なng-ifがなかったことを指摘するのが最善かもしれません。ng-showとng-hideにはブール値を返す関数が含まれていたため、これらすべてをng-ifで簡単に置き換えることができました。そうすることで、すべての内部ディレクティブが評価されなくなったように見えました。つまり、評価されているすべてのディレクティブの約3分の1に戻り、UIの読み込み時間が約500ミリ秒-1秒に高速化されました。(正確な秒を決定する方法はありません)

注:ディレクティブが評価されないという事実は、その下で何が起こっているかについての知識に基づいた推測です。

したがって、私の意見では、ページに要素を表示する必要がある場合(つまり、要素をチェックするためなど)、単に非表示にする場合は、ng-show / ng-hideを使用します。それ以外の場合はすべて、ng-ifを使用します。


1
はい、これがng-ifの目標だと思います。処理時間を短縮することです。このディレクティブは、いくつかのCSS疑似セレクターが原因であるだけではありません。良いポスト!1
パルトロミエザレウスキー

36

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

これは:first-child:last-childスタイリングに疑似セレクターを使用する場合に役立ちます。


:firstおよび:lastセレクターを使用するとはどういう意味ですか?
ステファンRolland 2013年


16

@EdSpencerは正しいです。多くの要素があり、ng-ifを使用して関連する要素のみをインスタンス化する場合、リソースを節約しています。@CodeHaterもある程度正しく、要素を頻繁に削除して表示する場合は、削除する代わりに非表示にするとパフォーマンスが向上する可能性があります。

ng-ifの主な使用例は、コンテンツが違法な場合に要素を明確に検証および排除できることです。たとえば、nullの画像名変数を参照するとエラーがスローされますが、ng-ifを実行してnullかどうかを確認すると、問題ありません。ng-showを実行した場合でも、エラーが発生します。


7

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はそれにフォーカスできません。このエラーはスクリプトの実行を停止するため、文字通りコードを破壊する可能性があります。ので注意してください!


これは本当の事実です。検証にフォームコントロールを使用している場合、ng-show / ng-hideを使用すると多くの問題が発生します。そして、表現に基づいて非表示/表示する複数のセクションがある場合。したがって、ng-show / hideを使用すると、要素は画面に表示されていなくても、要素はまだ存在し、検証は失敗します。so ng-if rescue you :)
NeverGiveUp161

5

@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にfalse値を指定して、コンソールでDOMを確認してください。入力ボックスに値を入力して、違いを確認してください。

<!DOCTYPE html>

こんにちは、プランカー!

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


2

事実、その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>

最初のリストでは、inn / ownスコープのon-clickイベント、show変数が変更されていますが、同じ名前の外部スコープの別の変数を監視しているため、ソリューションは機能しません。以下の場合には、我々だけ持って、それが動作する理由である変数を、。最初の試行を修正するには、を介して親/外部スコープから参照する必要があります。ng-ifng-showshowshow$parent.show


1
  1. ng-if falseの場合、DOMから要素が削除されます。つまり、これらの要素に関連付けられているすべてのイベント、ディレクティブが失われます。たとえば、いずれかの子要素をng-clickすると、ng-ifがfalseと評価された場合、その要素はDOMから削除され、trueの場合は再作成されます。

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

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


1

ng-showとng-hideは逆の方法で機能します。ただし、ng-ifを使用したng-hideまたはng-showの違いは、ng-ifを使用する場合、要素はdomに作成されますが、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

ちなみに、今私に起こったこと:ng-showはcssを介してコンテンツを非表示にします、しかし、それはdivのボタンであるはずの奇妙なグリッチをもたらしました。

下部に2つのボタンが付いたカードがあり、実際の状態に応じて、新しいエントリのある3番目の編集ボタンと交換されます。ng-show = falseを使用して左側のファイル(ファイルの最初に存在)を非表示にすると、次のボタンがカードの外側の右側の境界線で終了することがありました。ng-ifは、コードをまったく含めないことで修正します。(ng-showの代わりにng-ifを使用していくつかの隠された驚きがあるかどうか、ここで確認してください)


0

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

一方、ngShowはCSSルールを適用して非表示/表示を行います。

ほとんどの場合(常にではありません)で、これを要約します。物事を表示/非表示にするために1回限りのチェックng-ifが必要な場合は、画面上のユーザーアクションに基づいて物事を表示/非表示にする必要がある場合(チェック済みなど)チェックボックスをオンにしてテキストボックスを表示し、オフにしてからテキストボックスを非表示にするなど)、次に使用しますng-show


-17

ng-ifとng-showの興味深い違いの1つは次のとおりです。

セキュリティ

ng-ifブロックに存在するDOM要素は、その値がfalseの場合はレンダリングされません

ng-showの場合と同様に、ユーザーはInspect Element Windowを開いてその値をTRUEに設定できます。

そして、おっと、非表示にしようとしたコンテンツ全体が表示されます。これはセキュリティ違反です。:)


27
これは非常に弱いセキュリティの形式です。コンテンツがサーバーによってクライアントに提供される場合、コンテンツがDOMに存在するかどうかに関係なく、ユーザー/攻撃者がコンテンツにアクセスできると想定する必要があります。すべての承認ロジックはサーバーによって実行される必要があります。
tlrobinson

jspではなくhtmlについて考えてみてください。htmlコンポーネントにセキュリティを適用したい場合、つまり一部のコンポーネントをユーザーから非表示にしたい場合は、どうすればそれを実現できますか。また、構成がバックエンド用のサーバー側とフロントエンド用のクライアント側に分割されている場合はどうなりますか?
Ashish_B
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.