Apa perbedaan antara ng-if dan ng-show / ng-hide

427

Saya mencoba memahami perbedaan antara ng-ifdan ng-show/ ng-hide, tetapi mereka terlihat sama bagi saya.

Apakah ada perbedaan yang harus saya ingat memilih untuk menggunakan satu atau yang lain?

Stephane Rolland
sumber

Jawaban:

521

ng

The ngIfdirektif Menghapus atau recreates sebagian dari pohon DOM berdasarkan ekspresi. Jika ekspresi yang ditetapkan untuk ngIfmengevaluasi nilai palsu maka elemen tersebut dihapus dari DOM, jika tidak, klon elemen dimasukkan kembali ke dalam 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>

Ketika elemen dihapus menggunakan ngIfcakupannya dihancurkan dan cakupan baru dibuat ketika elemen dikembalikan. Lingkup yang dibuat di dalam ngIfmewarisi dari lingkup induknya menggunakan pewarisan prototypal.

Jika ngModeldigunakan di dalam ngIfuntuk mengikat JavaScript primitif yang didefinisikan dalam lingkup induk, setiap modifikasi yang dilakukan pada variabel dalam lingkup anak tidak akan mempengaruhi nilai dalam lingkup induk, misalnya

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

Untuk menyiasati situasi ini dan memperbarui model dalam lingkup induk dari dalam lingkup anak, gunakan objek:

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

Atau, $parentvariabel untuk merujuk objek lingkup induk:

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

ngShow

The ngShowdirektif menunjukkan atau menyembunyikan elemen HTML yang diberikan berdasarkan ekspresi yang diberikan kepada ngShowatribut. Elemen ditampilkan atau disembunyikan dengan menghapus atau menambahkan ng-hidekelas CSS ke elemen. Kelas .ng-hideCSS sudah ditentukan sebelumnya dalam AngularJS dan mengatur gaya tampilan ke none (menggunakan !importantbendera).

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

Ketika ngShowekspresi mengevaluasi falsemaka ng-hidekelas CSS ditambahkan ke classatribut pada elemen yang menyebabkannya tersembunyi. Ketika true, ng-hidekelas CSS dihapus dari elemen yang menyebabkan elemen tidak muncul tersembunyi.

Selalu Belajar
sumber
31
Petunjuk: Dengan menghapus elemen HTML itu sendiri dengan ng-ifmodel, ditambahkan oleh ng-model, tidak ada lagi.
mrzmyr
3
@CodeHater Saya telah berhasil meningkatkan ng-jika lebih ng-show / ng-hide pada halaman yang seharusnya memiliki dom yang besar. Tampaknya membuat halaman terasa lebih cepat, tetapi tidak berarti analisis ilmiah.
Ed Spencer
Bagian saya mengalami masalah dengan pemahaman sepenuhnya adalah bagaimana / mengapa ketika Anda memiliki objek dalam model data.inputitu berfungsi ... tetapi datasendirian dalam model tidak berfungsi. @CodeHater
Mark Pieszak - Trilon.io
7
@mcpDESIGNS ngIfmembuat ruang lingkup baru, jadi dengan melihat contoh di atas, nested ngModelakan membuat datamodel baru meskipun model dengan nama yang sama ada di lingkup induk. Tetapi ketika Anda menggunakan notasi titik, Anda membuat JS mencari rantai prototipe ruang lingkup. Jadi jika tidak menemukan nilai dalam cakupan saat ini, ia akan mencoba mencarinya di lingkup induk dan seterusnya. Beberapa arahan lain yang membuat ruang lingkup yang berbeda ngInclude, ngRepeat. Semoga ini jelas sekarang. :)
AlwaysALearner
3
Mana yang lebih baik untuk kinerja? Saya pikir ng-show dan ng-hide bukan?
tom10271
97

Mungkin hal yang menarik untuk disampaikan, adalah perbedaan antara prioritas di antara keduanya.

Sejauh yang saya tahu, arahan ng-if memiliki salah satu prioritas tertinggi (jika bukan yang tertinggi) dari semua arahan Angular. Yang berarti: itu akan berjalan PERTAMA sebelum semua lainnya, arahan diprioritaskan rendah. Fakta bahwa ia menjalankan PERTAMA, berarti bahwa secara efektif, elemen dihapus sebelum arahan dalam diproses. Atau setidaknya: itulah yang saya lakukan.

Saya mengamati dan menggunakan ini di UI saya sedang membangun untuk pelanggan saya saat ini. Seluruh UI cukup padat, dan memiliki ng-show dan ng-hide di atasnya. Tidak terlalu detail, tapi saya membangun komponen generik, yang bisa dikelola menggunakan konfigurasi JSON, jadi saya harus melakukan beberapa pergantian di dalam templat. Ada hadiah ng-repeat, dan di dalam ng-repeat, sebuah tabel ditampilkan, yang memiliki banyak pertunjukan, ng-jangat dan bahkan ng-switch hadir. Mereka ingin menunjukkan setidaknya 50 pengulangan dalam daftar, yang akan menghasilkan kurang lebih 1500-2000 arahan yang harus diselesaikan. Saya memeriksa kode, dan Java backend + custom JS di bagian depan akan memakan waktu sekitar 150ms untuk memproses data, dan kemudian Angular akan mengunyah sekitar 2-3 detik di atasnya, sebelum menampilkan. Pelanggan tidak mengeluh, tapi saya terkejut :-)

Dalam pencarian saya, saya menemukan petunjuk ng-if. Sekarang, mungkin yang terbaik untuk menunjukkan bahwa pada saat menyusun UI ini, tidak ada ng-jika tersedia. Karena ng-show dan ng-hide memiliki fungsi di dalamnya, yang mengembalikan booleans, saya dapat dengan mudah menggantinya dengan ng-if. Dengan melakukan itu, semua arahan batin tampaknya tidak lagi dievaluasi. Itu berarti saya kembali ke sekitar sepertiga dari semua arahan yang sedang dievaluasi, dan dengan demikian, UI mempercepat hingga sekitar 500ms - 1 detik waktu pemuatan. (Saya tidak punya cara untuk menentukan detik yang tepat)

Perhatikan: fakta bahwa arahan tidak dievaluasi, adalah tebakan yang berpendidikan tentang apa yang terjadi di bawahnya.

Jadi, menurut saya: jika Anda membutuhkan elemen untuk hadir di halaman (yaitu: untuk memeriksa elemen, atau apa pun), tetapi hanya disembunyikan, gunakan ng-show / ng-hide. Dalam semua kasus lain, gunakan ng-jika.

Goris
sumber
1
Ya, saya kira ini adalah tujuan dari ng-if: untuk mengurangi waktu pemrosesan. Arahan ini pasti ada tidak hanya karena beberapa pseudoselektor CSS. Pos bagus! +1
Bartłomiej Zalewski
16

@EdSpencer sudah benar. Jika Anda memiliki banyak elemen dan Anda menggunakan ng-jika hanya instantiate yang relevan, Anda menghemat sumber daya. @ Codode juga agak benar, jika Anda akan menghapus dan menunjukkan elemen sangat sering, menyembunyikannya alih-alih menghapusnya dapat meningkatkan kinerja.

Kasus penggunaan utama yang saya temukan untuk ng-if adalah memungkinkan saya untuk memvalidasi dan menghilangkan elemen secara bersih jika kontennya ilegal. Misalnya saya bisa merujuk ke variabel nama gambar nol dan itu akan menimbulkan kesalahan tetapi jika saya ng-jika dan memeriksa apakah itu nol, semuanya baik-baik saja. Jika saya melakukan pertunjukan ng, kesalahan masih akan menyala.

AturSams
sumber
7

Satu hal penting yang perlu diperhatikan tentang ng-if dan ng-show adalah bahwa ketika menggunakan kontrol formulir lebih baik digunakan ng-ifkarena itu benar-benar menghilangkan elemen dari dom.

Perbedaan ini penting karena jika Anda membuat bidang input dengan required="true"dan kemudian mengatur ng-show="false"untuk menyembunyikannya, Chrome akan melempar kesalahan berikut ketika pengguna mencoba mengirimkan formulir:

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

Alasannya adalah bidang input ada dan itu ada requiredtetapi karena tersembunyi Chrome tidak bisa fokus padanya. Ini benar-benar dapat memecahkan kode Anda karena kesalahan ini menghentikan eksekusi skrip. Jadi hati-hati!

supersan
sumber
Ini adalah kenyataan, jika Anda menggunakan kontrol formulir untuk validasi maka Anda akan sangat menderita jika Anda menggunakan ng-show / ng-hide. Dan jika Anda memiliki beberapa bagian yang disembunyikan / ditampilkan berdasarkan ekspresi. Jadi jika Anda menggunakan ng-show / sembunyikan elemen akan tetap ada dan validasi akan gagal, meskipun mereka tidak ada di layar. jadi ng-jika menyelamatkan Anda :)
NeverGiveUp161
5

@Gajus Kuizinas dan @CodeHater benar. Di sini saya hanya memberi contoh. Sementara kami bekerja dengan ng-if, jika nilai yang diberikan salah maka seluruh elemen html akan dihapus dari DOM. dan jika nilai yang diberikan benar, maka elemen html akan terlihat pada DOM. Dan cakupannya akan berbeda dibandingkan dengan cakupan induknya. Tetapi dalam kasus ng-show, itu hanya akan menunjukkan dan menyembunyikan elemen-elemen berdasarkan nilai yang diberikan. Tapi selalu tetap di DOM. Hanya visibilitas yang berubah sesuai nilai yang ditetapkan.

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

Semoga contoh ini akan membantu Anda dalam memahami ruang lingkup. Coba berikan nilai-nilai salah untuk ng-show dan ng-if dan periksa DOM di konsol. Coba masukkan nilai dalam kotak input dan amati perbedaannya.

<!DOCTYPE html>

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


sumber
2

Fakta, ng-ifarahan itu, tidak seperti ng-show, menciptakan ruang lingkupnya sendiri, mengarah pada perbedaan praktis yang menarik:

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>

Pada daftar pertama, on-clickevent, showvariabel, dari bawaan / lingkup sendiri , diubah, tetapi ng-ifmenonton pada variabel lain dari luar lingkup dengan nama yang sama, sehingga solusi tidak berfungsi. Jika ng-showkita memiliki satu-satunya showvariabel, itu sebabnya ia bekerja. Untuk memperbaiki upaya pertama, kita harus merujuk showdari induk / luar lingkup via $parent.show.

Slava Utesinov
sumber
1
  1. ng-jika if false akan menghapus elemen dari DOM. Ini berarti bahwa semua acara Anda, arahan yang melekat pada elemen-elemen itu akan hilang. Misalnya, ng-klik ke salah satu elemen anak, ketika ng-jika bernilai false, elemen itu akan dihapus dari DOM dan lagi ketika benar itu dibuat ulang.

  2. ng-show / ng-hide tidak menghapus elemen dari DOM. Menggunakan gaya CSS (.ng-hide) untuk menyembunyikan / menampilkan elemen. Dengan cara ini acara Anda, arahan yang melekat pada anak-anak tidak akan hilang.

  3. ng-if membuat lingkup anak sementara ng-show / ng-hide tidak.

Amay Kulkarni
sumber
1

ng-show dan ng-hide bekerja dengan cara yang berlawanan. Tetapi perbedaan antara ng-hide atau ng-show dengan ng-if adalah, jika kita menggunakan ng-if maka elemen akan dibuat di dom tetapi dengan elemen ng-hide / ng-show akan disembunyikan sepenuhnya.

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. 
pengguna1001
sumber
0

Untuk diketahui, hal yang terjadi pada saya sekarang: ng-show memang menyembunyikan konten melalui css, ya, tapi itu menghasilkan gangguan aneh di div yang seharusnya berupa tombol.

Saya memiliki kartu dengan dua tombol di bagian bawah dan tergantung pada keadaan sebenarnya, salah satunya ditukar dengan yang ketiga, misalnya tombol edit dengan entri baru. Menggunakan ng-show = false untuk menyembunyikan yang kiri (ada lebih dulu di dalam file) itu terjadi bahwa tombol berikut berakhir dengan perbatasan kanan di luar kartu. ng-jika memperbaikinya dengan tidak memasukkan kode sama sekali. (Cukup periksa di sini jika ada beberapa kejutan tersembunyi menggunakan ng-jika alih-alih ng-show)

helius
sumber
0

ngIf membuat manipulasi pada DOM dengan menghapus atau membuat ulang elemen.

Sedangkan ngShow menerapkan aturan css untuk menyembunyikan / menampilkan sesuatu.

Untuk sebagian besar kasus (tidak selalu) , saya akan meringkas ini sebagai, jika Anda memerlukan pemeriksaan satu kali untuk menampilkan / menyembunyikan sesuatu, gunakan ng-if, jika Anda perlu menampilkan / menyembunyikan sesuatu berdasarkan tindakan pengguna di layar (seperti dicentang kotak centang kemudian tampilkan kotak teks, hapus centang lalu sembunyikan kotak teks dll.), lalu gunakanng-show

curiousBoy
sumber
-17

Satu perbedaan menarik dalam ng-if dan ng-show adalah:

KEAMANAN

Elemen DOM yang ada di blok ng-if tidak akan diberikan jika nilainya salah

dimana dalam hal ng-show, pengguna dapat membuka Jendela Elemen Inspeksi Anda dan mengatur nilainya ke TRUE.

Dan dengan teriakan, seluruh konten yang dimaksudkan untuk disembunyikan akan ditampilkan, yang merupakan pelanggaran keamanan. :)

Ashish_B
sumber
27
Ini adalah bentuk keamanan yang sangat lemah. Jika konten diberikan kepada klien oleh server, maka Anda harus menganggap pengguna / penyerang dapat mengaksesnya, terlepas dari apakah itu ada atau tidak di DOM. Semua logika otorisasi harus ditegakkan oleh server.
tlrobinson
pikirkan tentang html daripada jsp ... sekarang jika Anda ingin menegakkan keamanan pada komponen html .. yaitu jika Anda ingin menyembunyikan beberapa komponen dari pengguna ... bagaimana Anda mencapainya. Dan apa yang terjadi jika konfigurasi Anda dibagi menjadi sisi server untuk backend dan sisi klien untuk front end ..
Ashish_B