Sự khác biệt giữa @ViewChild và @ContentChild là gì?


187

Góc 2 cung cấp @ViewChild, @ViewChildren, @ContentChild@ContentChildrentrang trí để truy vấn các yếu tố hậu duệ của một thành phần.

Sự khác biệt giữa hai cái đầu tiên và hai cái sau là gì?


3
Liên kết này đã giúp tôi blog.mgechev.com/2016/01/23/ khăn sau khi đọc các câu trả lời dưới đây. Chúc mừng :)
Gopinath Shiva

Câu trả lời:


254

Tôi sẽ trả lời câu hỏi của bạn bằng thuật ngữ Shadow DOMLight DOM (nó đến từ các thành phần web, xem thêm tại đây ). Nói chung:

  • Shadow DOM - là một DOM nội bộ của thành phần được xác định bởi bạn (với tư cách là người tạo ra thành phần ) và ẩn khỏi người dùng cuối. Ví dụ:
@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 - là một DOM mà người dùng cuối cung cấp thành phần của bạn vào thành phần của bạn. Ví dụ:
@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 { /* ... */ }

Vì vậy, câu trả lời cho câu hỏi của bạn khá đơn giản:

Sự khác biệt giữa @ViewChildren@ContentChildren@ViewChildrentìm kiếm các phần tử trong Shadow DOM trong khi @ContentChildrentìm kiếm chúng trong Light DOM.


10
Mục nhập blog blog.mgechev.com/2016/01/23/ Khăn từ Minko Gechew có ý nghĩa hơn đối với tôi. @ContentChildren là những đứa trẻ, được chèn bởi phép chiếu nội dung (những đứa trẻ nằm giữa <ng-content> </ ng-content>). Từ Blog của Minkos: "Mặt khác, các phần tử ** được sử dụng giữa các thẻ mở và đóng của phần tử máy chủ của một thành phần nhất định được gọi là * nội dung con **." Shadow DOM và xem đóng gói trong Angular2 được mô tả ở đây: blog . Dùtram.io / angang/2015 / 06/29 / .
westor

4
Đối với tôi nghe có vẻ như @TemplateChildren(thay vì @ViewChildren) hoặc @HostChildren(thay vì @ContentChildren) sẽ là những cái tên hay hơn nhiều, vì trong bối cảnh như vậy, mọi thứ chúng ta đang nói đều liên quan đến chế độ xem và ràng buộc wrt cũng liên quan đến nội dung.
superjos

34
@ViewChildren== con của bạn; @ContentChildren== đứa trẻ khác của ai đó
thẳng thắn

105

Như tên cho thấy, @ContentChild@ContentChildrencác truy vấn sẽ trả về các chỉ thị hiện có bên trong <ng-content></ng-content>phần tử của chế độ xem của bạn, trong khi đó @ViewChild@ViewChildrenchỉ nhìn trực tiếp vào các phần tử trên mẫu xem của bạn.


Vì vậy, sử dụng @ViewChild (ren) trừ khi bạn có các thành phần trong chế độ xem của mình trong trường hợp nào rơi trở lại @ContentChild (ren)?
Ben Taliadoros

31

Video này từ Angular Connect có thông tin tuyệt vời về ViewChildren, ViewChild, ContentChildren và ContentChild https://youtu.be/4YmnbGoh49U

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

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

Từ my-widgetquan điểm của, comp-aContentChildcomp-bViewChild. CompomentChildrenViewChildrentrả về một lần lặp trong khi xChild trả về một thể hiện duy nhất.


Đây là lời giải thích tốt hơn. Cảm ơn :)
Javeed

Bạn đã làm một ví dụ rõ ràng và đơn giản, nhưng mẫu của MyWidget <comp-b><ng-content></ng-content></comp-b>phải không?
ARJEL

1

Hãy lấy một ví dụ, Chúng ta có một thành phần gia đình và một thành phần con và bên trong thành phần con một thành phần con nhỏ.

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

Bây giờ bạn có thể lấy tất cả các phần tử con trong ngữ cảnh của thành phần gia đình với @viewChildren vì chúng được thêm trực tiếp vào mẫu của thành phần gia đình. Nhưng, khi bạn cố gắng truy cập <small-child>phần tử từ ngữ cảnh của thành phần con thì bạn không thể truy cập phần tử này vì nó không được thêm trực tiếp vào mẫu thành phần con. Nó được thêm vào thông qua chiếu nội dung vào thành phần con theo thành phần nhà. Đây là nơi @contentChild đến và bạn có thể lấy nó bằng @contentChild.

Sự khác biệt xảy ra khi bạn cố gắng truy cập các yếu tố tham chiếu trong bộ điều khiển. Bạn có thể truy cập lấy tất cả các yếu tố được thêm trực tiếp vào mẫu của thành phần bởi @viewChild. Nhưng bạn không thể lấy tham chiếu các phần tử được chiếu với @viewChild Để truy cập phần tử được chiếu, bạn phải sử dụng @contentChild.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.