เมื่อใดที่จะชอบ ng-if vs. ng-show / ng-hide?


516

ฉันเข้าใจng-showและng-hideส่งผลต่อคลาสที่ตั้งค่าไว้บนองค์ประกอบและng-ifควบคุมว่าจะให้องค์ประกอบแสดงผลเป็นส่วนหนึ่งของ DOM หรือไม่

จะมีแนวทางในการเลือกng-ifมากกว่าng-show/ ng-hideหรือในทางกลับกัน?


5
เป็นไปได้ที่ซ้ำกันของความแตกต่างระหว่าง ng-if และ ng-show / ng-hide
อะไร

1
ไม่เกี่ยวข้องกับภาษาโผ
naXa

คำตอบ:


703

ขึ้นอยู่กับกรณีการใช้งานของคุณ แต่เพื่อสรุปความแตกต่าง:

  1. ng-ifจะลบองค์ประกอบออกจาก DOM ซึ่งหมายความว่าตัวจัดการของคุณทั้งหมดหรือสิ่งอื่นใดที่ติดอยู่กับองค์ประกอบเหล่านั้นจะหายไป ตัวอย่างเช่นหากคุณเชื่อมโยงตัวจัดการคลิกเข้ากับองค์ประกอบย่อยหนึ่งองค์ประกอบเมื่อng-ifประเมินเป็นเท็จองค์ประกอบนั้นจะถูกลบออกจาก DOM และตัวจัดการการคลิกของคุณจะไม่ทำงานอีกng-ifต่อไปแม้หลังจากประเมินเป็นจริงในภายหลังและแสดงองค์ประกอบนั้น คุณจะต้องใส่ตัวจัดการกลับเข้าไปใหม่
  2. ng-show/ng-hideไม่ลบองค์ประกอบออกจาก DOM มันใช้สไตล์ CSS เพื่อซ่อน / แสดงองค์ประกอบ (หมายเหตุ: คุณอาจต้องเพิ่มคลาสของคุณเอง) วิธีนี้เครื่องจัดการของคุณที่ติดมากับเด็กจะไม่สูญหาย
  3. ng-ifสร้างขอบเขตลูกในขณะที่ng-show/ng-hideไม่

องค์ประกอบที่ไม่ได้อยู่ใน DOM มีผลกระทบต่อประสิทธิภาพน้อยลงและเว็บแอปของคุณอาจดูเหมือนจะเร็วขึ้นเมื่อใช้เมื่อเทียบกับng-if ng-show/ng-hideจากประสบการณ์ของฉันความแตกต่างนั้นเล็กน้อย ภาพเคลื่อนไหวเป็นไปได้เมื่อใช้ทั้งสองng-show/ng-hideและng-ifตัวอย่างสำหรับทั้งในเอกสารประกอบเชิงมุม

ท้ายที่สุดคำถามที่คุณต้องตอบคือคุณสามารถลบองค์ประกอบออกจาก DOM หรือไม่?


19
คุณสามารถใช้ภาพเคลื่อนไหว CSS3 ng-ifได้ ตรวจสอบวรรคภาพเคลื่อนไหวและตัวอย่างในเอกสาร นอกจากนี้ยังมีng-hide/ng-showตัวเลือก css เช่น:first-childหรือ:nth-childไม่ทำงานอย่างถูกต้องเนื่องจากองค์ประกอบที่ซ่อนอยู่จะถูกนับด้วย
Łukasz Wojciechowski

4
บริการแอนิเมชันใน angular.dart ค่อนข้างใหม่ ในขณะที่เขียนนี้มันไม่สามารถใช้ได้
markovuksanovic

44
จุดแรกคุณไม่ใช่ปัญหาหากคุณใช้คำสั่ง (เช่น ng-click) เพื่อผูกตัวจัดการตามที่คุณควรจะเป็น
Kevin C.

9
นอกจากนี้ยังng-ifสร้างขอบเขตใหม่ในขณะที่ng-showไม่ได้
martin

8
ควรกล่าวถึงด้วยว่าการเพิ่มและลบองค์ประกอบออกจาก DOM สามารถทำให้เกิดค่าใช้จ่ายสูงหากทำบ่อย
Kevin C.

130

ดูที่นี่สำหรับ CodePen ที่แสดงให้เห็นถึงความแตกต่างในการทำงานของ ng-if / ng-show, DOM-wise

@markovuksanovic ตอบคำถามได้ดี แต่ฉันมาจากมุมมองอื่น: ฉันมักจะใช้ng-ifและนำองค์ประกอบเหล่านั้นออกจาก DOM ยกเว้น:

  1. ด้วยเหตุผลบางอย่างคุณจำเป็นต้องมี data-bindings และ$watch-es ในองค์ประกอบของคุณเพื่อให้สามารถใช้งานได้ในขณะที่มองไม่เห็น แบบฟอร์มอาจเป็นกรณีที่ดีสำหรับสิ่งนี้ถ้าคุณต้องการตรวจสอบความถูกต้องของอินพุตที่ไม่สามารถมองเห็นได้ในปัจจุบันเพื่อตรวจสอบว่าแบบฟอร์มทั้งหมดนั้นถูกต้องหรือไม่
  2. คุณกำลังใช้ตรรกะ stateful ที่ซับซ้อนอย่างแท้จริงกับตัวจัดการเหตุการณ์แบบมีเงื่อนไขตามที่กล่าวไว้ข้างต้น ที่กล่าวว่าหากคุณพบว่าตัวเองติดและแยกตัวจัดการด้วยตนเองเช่นคุณกำลังสูญเสียสถานะที่สำคัญเมื่อคุณใช้ ng-if ถามตัวเองว่าสถานะนั้นจะเป็นตัวแทนที่ดีขึ้นในแบบจำลองข้อมูลหรือไม่และตัวจัดการใช้เงื่อนไขตามคำสั่งทุกครั้ง องค์ประกอบมีการแสดงผล ใส่อีกวิธีหนึ่งการมี / ไม่มีตัวจัดการเป็นรูปแบบของข้อมูลสถานะ นำข้อมูลนั้นออกจาก DOM และเข้าสู่โมเดล การมี / ไม่มีตัวจัดการควรถูกกำหนดโดยข้อมูลและทำให้ง่ายต่อการสร้างใหม่

เชิงมุมเขียนได้ดีมาก มันรวดเร็วโดยพิจารณาว่ามันทำอะไร แต่สิ่งที่ทำคือกลุ่มของเวทมนตร์ที่ทำให้สิ่งที่ยาก (เช่นการผูกข้อมูลแบบสองทาง) ดูง่ายเล็กน้อย การทำให้ทุกสิ่งดูง่ายทำให้เกิดประสิทธิภาพการทำงานสูง คุณอาจตกใจเมื่อรู้ว่ามีหลายร้อยหรือหลายพันเท่าที่ฟังก์ชั่นเซทเทอร์ได้รับการประเมินในระหว่าง$digestรอบของ DOM ที่ก้อนใหญ่ไม่มีใครดู แล้วคุณก็รู้ว่าคุณมีองค์ประกอบที่มองไม่เห็นนับร้อยหรือร้อยทั้งหมดทำสิ่งเดียวกัน ...

เดสก์ท็อปอาจมีประสิทธิภาพเพียงพอที่จะแสดงผลปัญหาการประมวลผลความเร็ว JS ส่วนใหญ่ แต่ถ้าคุณพัฒนามือถือให้ใช้ ng-if ทุกครั้งที่เป็นไปได้อย่างมนุษย์ปุถุชน ความเร็วของ JS ยังมีความสำคัญกับโปรเซสเซอร์มือถือ การใช้ ng-if เป็นวิธีที่ง่ายมากในการเพิ่มประสิทธิภาพที่สำคัญซึ่งอาจมีค่าใช้จ่ายต่ำมาก


6
นอกจากนี้คำตอบที่ดีมาก มีบริบทที่ดีซึ่งช่วยในการตัดสินใจ ขอบคุณ
Sean

1
ng-showมีประโยชน์เมื่อคุณพูดแท็บแต่ละรายการที่มีเนื้อหาจำนวนมากที่ต้องใช้เวลาในการแสดงผล หลังจากการเรนเดอร์ครั้งแรกการย้ายไปมาระหว่างแท็บจะเกิดขึ้นทันทีในขณะที่ng-ifต้องการการเรนเดอร์ใหม่, เชื่อมเหตุการณ์ต่าง ๆ เป็นต้นข้อเสียอย่างที่คุณพูดก็คือ เชิงมุมหมดความต้องการng-ifshowwatch
poshest

53

จากประสบการณ์ของฉัน:

1) หากหน้าของคุณมีการสลับที่ใช้ ng-if / ng-show เพื่อแสดง / ซ่อนบางสิ่ง ng-if ทำให้เบราว์เซอร์ล่าช้ามากขึ้น (ช้าลง) ตัวอย่างเช่น: หากคุณมีปุ่มที่ใช้ในการสลับระหว่างสองมุมมอง ng-show น่าจะเร็วกว่า

2) ng-if จะสร้าง / ทำลายขอบเขตเมื่อประเมินเป็นจริง / เท็จ หากคุณมีคอนโทรลเลอร์ติดอยู่กับ ng-if รหัสคอนโทรลเลอร์นั้นจะถูกเรียกใช้งานทุกครั้งที่ ng-if ประเมินผลเป็นจริง หากคุณใช้ ng-show รหัสคอนโทรลเลอร์จะได้รับการดำเนินการเพียงครั้งเดียว ดังนั้นหากคุณมีปุ่มที่สลับระหว่างมุมมองหลายมุมมองการใช้ ng-if และ ng-show จะสร้างความแตกต่างอย่างมากในวิธีที่คุณเขียนรหัสคอนโทรลเลอร์ของคุณ


5
นั่นเป็นเรื่องใหญ่จริง! ng-if ไม่จำเป็นต้องทำให้ส่วนหน้าของคุณเร็วขึ้น ขึ้นอยู่กับความต้องการของคุณ ที่จริงแล้วมันสามารถหลีกเลี่ยงได้หากคุณใช้ในสถานการณ์ที่ผิด
Thiago C. S Ventura

1
แต่ตามที่ฉันในฐานะ ng-if ไม่ได้แสดงผลบน DOM ดังนั้นจึงรวดเร็วเมื่อเปรียบเทียบกับ ng-show / hide ฉันผิดโปรดให้ฉันแก้ไข ณ จุดนั้น
Pardeep Jain

1
ng-if จะเร็วกว่าหากประเมินว่าเป็นเท็จเนื่องจากอย่างที่คุณพูดคุณไม่จำเป็นต้องแทรกลงใน DOM แต่ถ้าเป็นจริงแล้วคุณมีค่าใช้จ่ายในการแทรก - อาจจะค่อนข้างซับซ้อน - องค์ประกอบใน DOM
Mawg กล่าวว่าคืนสถานะโมนิก้า

"2) ng-if จะสร้าง / ทำลายขอบเขตเมื่อประเมินเป็นจริง / เท็จหากคุณมีคอนโทรลเลอร์ที่แนบกับ ng-if รหัสคอนโทรลเลอร์นั้นจะถูกเรียกใช้งานทุกครั้งที่"
The Red Pea

35

คำตอบนั้นไม่ง่าย:

มันขึ้นอยู่กับเครื่องเป้าหมาย (มือถือเทียบกับเดสก์ท็อป) มันขึ้นอยู่กับลักษณะของข้อมูลเบราว์เซอร์ระบบปฏิบัติการฮาร์ดแวร์ที่ทำงานบน ... คุณจะต้องสร้างมาตรฐานหากคุณต้องการรู้จริง ๆ

มันเป็นปัญหาการคำนวณหน่วยความจำส่วนใหญ่ ... เช่นเดียวกับปัญหาด้านประสิทธิภาพส่วนใหญ่ความแตกต่างอาจมีความสำคัญกับองค์ประกอบที่ซ้ำ ๆ (n) เช่นรายการโดยเฉพาะอย่างยิ่งเมื่อซ้อน (nxn หรือแย่กว่า) และการคำนวณที่คุณใช้ในองค์ประกอบเหล่านี้ :

  • ng-show : หากองค์ประกอบทางเลือกเหล่านั้นมักมีอยู่ (หนาแน่น) เช่นพูดว่า 90% ของเวลามันอาจจะเร็วกว่าที่จะให้พวกเขาพร้อมและแสดง / ซ่อนเฉพาะโดยเฉพาะอย่างยิ่งถ้าเนื้อหาของพวกเขาราคาถูก (แค่ข้อความธรรมดาไม่มีอะไรเลย เพื่อคำนวณหรือโหลด) วิธีนี้ใช้หน่วยความจำเมื่อเติม DOM ด้วยองค์ประกอบที่ซ่อนอยู่ แต่เพียงแสดง / ซ่อนบางสิ่งที่มีอยู่แล้วน่าจะเป็นการใช้งานที่ถูกสำหรับเบราว์เซอร์

  • ng-if : หากองค์ประกอบที่ตรงกันข้ามมีแนวโน้มว่าจะไม่แสดง (กระจัดกระจาย) เพียงแค่สร้างและทำลายพวกเขาแบบเรียลไทม์โดยเฉพาะอย่างยิ่งหากเนื้อหาของพวกเขามีราคาแพงที่จะได้รับ (การคำนวณ / เรียง / กรอง / กรองภาพสร้างภาพ) เหมาะสำหรับองค์ประกอบที่หายากหรือ 'ตามคำขอ' ช่วยประหยัดหน่วยความจำในแง่ของการไม่เติม DOM แต่สามารถใช้การคำนวณจำนวนมาก (การสร้าง / ทำลายองค์ประกอบ) และแบนด์วิดท์ (รับเนื้อหาจากระยะไกล) นอกจากนี้ยังขึ้นอยู่กับจำนวนที่คุณคำนวณในมุมมอง (การกรอง / การเรียงลำดับ) เทียบกับสิ่งที่คุณมีในโมเดล (ข้อมูลที่เรียงลำดับล่วงหน้า / กรองล่วงหน้า)


2
คำตอบอื่น ๆ สำหรับข้อเท็จจริงทางเทคนิค หนึ่งนี้สำหรับภูมิปัญญา คุณได้สร้างแอพเชิงมุมที่ไม่สำคัญเลย! 1
poshest

ปัญหานี้มีมากกว่าเชิงมุมมันเป็นปัญหาพื้นฐานในวิทยาการคอมพิวเตอร์มีประเด็นหนึ่งที่วิธีหนึ่งมีประสิทธิภาพมากกว่าอีกวิธีหนึ่ง โดยปกติสิ่งนี้สามารถพบได้ผ่านการเปรียบเทียบ ดังนั้นคุณสามารถสลับไปมาระหว่างวิธีการหนึ่งและวิธีอื่นได้โดยขึ้นอยู่กับจำนวนรายการ ... หัวข้อที่คล้ายกัน: math.stackexchange.com/questions/1632739/…
Christophe Roussy

12

หมายเหตุสำคัญหนึ่ง:

ngIf (ไม่เหมือน ngShow) มักจะสร้างขอบเขตของเด็กที่อาจให้ผลลัพธ์ที่ไม่คาดคิด

ฉันมีปัญหาเกี่ยวกับสิ่งนี้และฉันใช้เวลามากในการคิดว่าเกิดอะไรขึ้น

(คำสั่งของฉันกำลังเขียนค่ารุ่นไปยังขอบเขตที่ไม่ถูกต้อง)

ดังนั้นเพื่อประหยัดผมของคุณเพียงใช้ ngShow จนกว่าคุณจะทำงานช้าเกินไป

ความแตกต่างของการทำงานนั้นแทบจะไม่น่าสังเกตเลยและฉันก็ยังไม่แน่ใจว่าใครที่ชอบคือมันโดยไม่ต้องทดสอบ ...


8
ใช้$parent.scopevarในการผูกข้อมูลภายในngIfจะแก้ไขสิ่งต่าง ๆ เช่นปัญหาขอบเขตเด็กเมื่อใช้ngIf
meconroy

2
สิ่งนี้ไม่เป็นความจริงทั้งหมด (ความคิดเห็นดั้งเดิมของ @ @ user2173353 นั่นคือ) หากคุณยึดมั่นในแนวปฏิบัติที่ดีคุณจะไม่มีปัญหา นั่นเป็นกฎพื้นฐานที่ค่อนข้างดี: "ถ้าไม่มีจุดคุณกำลังทำผิด" ดูที่นี่สำหรับการสาธิตวิธีการทำงาน: bit.ly/1SPv4wL อีกหนึ่งการอ้างอิงที่ดี (ดูข้อผิดพลาด # 2): bit.ly/1QfFeWd > (คำสั่งของฉันกำลังเขียนค่าของแบบจำลองไปยังขอบเขตที่ไม่ถูกต้อง) นี่คือผลลัพธ์ของการไม่ยึดติดกับแนวปฏิบัติด้านบน
piotr.d

1
@ piotr.d คุณถูกต้อง แต่นั่นไม่ใช่สิ่งที่ผู้เริ่มต้นอาจต้องให้ความสำคัญและมีแนวปฏิบัติที่ดีอีกอย่างหนึ่งที่บอกว่าเป็นการดีกว่าที่จะออกจากการปรับปรุงประสิทธิภาพในตอนท้าย (โดยเฉพาะการปรับปรุงประสิทธิภาพที่อาจไม่ปรับปรุงในความเป็นจริง ) ฉันเคยเห็นคนที่ngIfเชื่อว่าสิ่งนี้จะปรับปรุงประสิทธิภาพการทำงานทุกที่ สิ่งนี้ไม่เป็นความจริงและไม่สามารถบอกได้ว่าสิ่งใดดีที่สุดngIfหรือngShowไม่มีการทดสอบหรือการวิเคราะห์เชิงลึกในกรณีเฉพาะ ดังนั้นฉันยังคงแนะนำให้ลืมngIfจนกว่าจะมีใครเห็นประสิทธิภาพที่ไม่ดีหรือรู้ว่าเขากำลังทำอะไรอยู่
user2173353

2
จุดดี. แต่การใช้ controllerAs ทำให้สิ่งนี้ไม่ใช่ปัญหา ดูตัวอย่างเช่นใช้จอห์นพ่อของบน controllerAs และ VM
jsruok

4

ng-if บน ng-include และ ng-controller จะมีผลกระทบอย่างมากกับ ng-include มันจะไม่โหลดบางส่วนที่ต้องการและไม่ดำเนินการจนกว่าการตั้งค่าสถานะเป็นจริงบน ng-controller มันจะไม่โหลดตัวควบคุมเว้นแต่จะตั้งค่าสถานะ จริง แต่ปัญหาคือเมื่อแฟล็กได้รับ false ใน ng-if มันจะลบออกจาก DOM เมื่อแฟล็กได้รับจริงมันจะรีโหลด DOM ในกรณีนี้ ng-show ดีกว่าสำหรับการแสดงครั้งเดียว ng-if ดีกว่า


4

ถ้าคุณใช้ ng-show or ng-hideเนื้อหา (เช่นรูปขนาดย่อจากเซิร์ฟเวอร์) จะโหลดโดยไม่คำนึงถึงค่าของนิพจน์ แต่จะแสดงตามค่าของนิพจน์

หากคุณใช้ng-ifเนื้อหาจะถูกโหลดเฉพาะในกรณีที่การแสดงออกของ ng-if ประเมินว่าเป็นความจริง

การใช้ ng-if เป็นความคิดที่ดีในสถานการณ์ที่คุณกำลังจะโหลดข้อมูลหรือภาพจากเซิร์ฟเวอร์และแสดงเฉพาะขึ้นอยู่กับการโต้ตอบของผู้ใช้ วิธีนี้การโหลดหน้าเว็บของคุณจะไม่ถูกบล็อกโดยงานที่ไม่จำเป็นซึ่งไม่จำเป็น


สิ่งนี้มีประโยชน์เป็นพิเศษเนื่องจากเบราว์เซอร์ส่วนใหญ่จะโหลดรูปภาพแม้ว่า CSS จะซ่อนคอนเทนเนอร์ DOM ไว้ พวกเขามักจะมองหาsrcคุณสมบัติของimgแท็กเมื่อมันได้รับการโหลด!
Christophe Roussy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.