@ViewChild กับ @ContentChild แตกต่างกันอย่างไร


189

เชิงมุม 2 มี@ViewChild, @ViewChildren, @ContentChildและ@ContentChildrenตกแต่งสำหรับการสอบถามองค์ประกอบลูกหลานองค์ประกอบของ

ความแตกต่างระหว่างสองคนแรกและสองหลังคืออะไร?


3
ลิงก์นี้ช่วยฉันblog.mgechev.com/2016/01/23/…หลังจากอ่านคำตอบด้านล่าง ไชโย :)
Gopinath Shiva

คำตอบ:


256

ฉันจะตอบคำถามของคุณโดยใช้คำศัพท์Shadow DOMและLight DOM (มาจากส่วนประกอบของเว็บดูเพิ่มเติมที่นี่ ) โดยทั่วไป:

  • Shadow DOM - เป็น DOM ภายในของคอมโพเนนต์ที่คุณกำหนดไว้(ในฐานะผู้สร้างส่วนประกอบ ) และซ่อนจากผู้ใช้ปลายทาง ตัวอย่างเช่น:
@Component({
  selector: 'some-component',
  template: `
    <h1>I am Shadow DOM!</h1>
    <h2>Nice to meet you :)</h2>
    <ng-content></ng-content>
  `;
})
class SomeComponent { /* ... */ }
  • Light DOM - เป็น DOM ที่ผู้ใช้ของส่วนประกอบของคุณจัดหาให้ในส่วนประกอบของคุณ ตัวอย่างเช่น:
@Component({
  selector: 'another-component',
  directives: [SomeComponent],
  template: `
    <some-component>
      <h1>Hi! I am Light DOM!</h1>
      <h2>So happy to see you!</h2>
    </some-component>
  `
})
class AnotherComponent { /* ... */ }

ดังนั้นคำตอบสำหรับคำถามของคุณนั้นง่ายมาก:

ความแตกต่างระหว่าง@ViewChildrenและ@ContentChildrenคือ@ViewChildrenมองหาองค์ประกอบใน Shadow DOM ขณะที่ค้นหาองค์ประกอบ@ContentChildrenเหล่านี้ใน Light DOM


10
บล็อกรายการblog.mgechev.com/2016/01/23/…จาก Minko Gechew ทำให้ฉันมีเหตุผลมากขึ้น @ContentChildren เป็นเด็ก ๆ แทรกโดยการฉายเนื้อหา (เด็ก ๆ ระหว่าง <ng-content> </ng-content>) จากบล็อกของ Minkos: "ในทางกลับกันองค์ประกอบ ** ที่ใช้ระหว่างแท็กเปิดและปิดขององค์ประกอบโฮสต์ขององค์ประกอบที่กำหนดเรียกว่า * content children **" DOM เงาและมุมมองการห่อหุ้มใน Angular2 สืบทอดมาที่นี่: บล็อก . buttram.io/angular/2015/06/29/
ตะวันตก

4
สำหรับฉันดูเหมือนว่า@TemplateChildren(แทน@ViewChildren) หรือ @HostChildren(แทน@ContentChildren) จะเป็นชื่อที่ดีกว่ามากอย่างเช่นในบริบทที่ทุกสิ่งที่เรากำลังพูดถึงนั้นเกี่ยวข้องกับมุมมองและการเชื่อมโยง WRT ก็เกี่ยวข้องกับเนื้อหาด้วย
superjos

35
@ViewChildren== ลูกของคุณเอง; @ContentChildren== ลูกของคนอื่น
candidj

107

ตามชื่อที่แนะนำ@ContentChildและ@ContentChildrenเคียวรีจะส่งคืนคำสั่งที่มีอยู่ภายใน<ng-content></ng-content>องค์ประกอบของมุมมองของคุณในขณะที่@ViewChildและ@ViewChildrenดูเฉพาะองค์ประกอบที่อยู่บนเทมเพลตมุมมองของคุณโดยตรง


ดังนั้นใช้ @ViewChild (ren) เว้นแต่ว่าคุณมีส่วนประกอบในมุมมองของคุณซึ่งในกรณีใดกลับไปที่ @ContentChild (ren)?
Ben Taliadoros

31

วิดีโอจาก Angular Connect มีข้อมูลที่ยอดเยี่ยมเกี่ยวกับ ViewChildren, ViewChild, ContentChildren และ ContentChild https://youtu.be/4YmnbGoh49U

@Component({
  template: `
    <my-widget>
      <comp-a/>
    </my-widget>
`
})
class App {}

@Component({
  selector: 'my-widget',
  template: `<comp-b/>`
})
class MyWidget {}

จากmy-widgetมุมมองของ 's, comp-aเป็นContentChildและเป็นcomp-b และคืนค่า iterable ในขณะที่ xChild คืนค่าอินสแตนซ์เดียวViewChildCompomentChildrenViewChildren


นี่คือคำอธิบายที่ดีกว่า ขอบคุณ :)
Javeed

คุณทำตัวอย่างที่ชัดเจนและเรียบง่าย แต่แม่แบบของ MyWidget ควรเป็น <comp-b><ng-content></ng-content></comp-b>ต้องหรือไม่
arjel

1

ให้ยกตัวอย่างเรามีองค์ประกอบภายในบ้านหนึ่งองค์ประกอบและองค์ประกอบย่อยหนึ่งองค์ประกอบและองค์ประกอบย่อยภายในองค์ประกอบย่อยหนึ่งองค์ประกอบย่อย

<home>
     <child>
           <small-child><small-child>
     </child>
</home>

ตอนนี้คุณสามารถคว้าองค์ประกอบลูกทั้งหมดในบริบทขององค์ประกอบภายในบ้านด้วย @viewChildren ได้เนื่องจากสิ่งเหล่านี้จะถูกเพิ่มเข้าไปในแม่แบบขององค์ประกอบภายในบ้านโดยตรง แต่เมื่อคุณพยายามเข้าถึง<small-child>องค์ประกอบจากบริบทขององค์ประกอบลูกคุณจะไม่สามารถเข้าถึงองค์ประกอบได้เนื่องจากไม่ได้เพิ่มโดยตรงในแม่แบบองค์ประกอบลูก มันถูกเพิ่มผ่านการฉายเนื้อหาลงในองค์ประกอบลูกโดยองค์ประกอบบ้าน นี่คือที่มาของ @contentChild และคุณสามารถคว้ามันได้ด้วย @contentChild

ความแตกต่างเกิดขึ้นเมื่อคุณพยายามเข้าถึงการอ้างอิงองค์ประกอบในคอนโทรลเลอร์ คุณสามารถเข้าถึงคว้าองค์ประกอบทั้งหมดที่เพิ่มลงในเทมเพลตของส่วนประกอบโดยตรงโดย @viewChild แต่คุณไม่สามารถคว้าการอ้างอิงองค์ประกอบที่ฉายด้วย @viewChild ในการเข้าถึงองค์ประกอบที่ฉายไว้คุณจะต้องใช้ @contentChild

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.