Nhiều ng-content


96

Tôi đang cố gắng tạo một thành phần tùy chỉnh bằng cách sử dụng nhiều ng-contenttrong Angular 6, nhưng điều này không hoạt động và tôi không biết tại sao.

Đây là mã thành phần của tôi:

<div class="header-css-class">
    <ng-content select="#header"></ng-content>
</div>
<div class="body-css-class">
    <ng-content select="#body"></ng-content>
</div>

Tôi đang cố gắng sử dụng thành phần này ở một nơi khác và hiển thị hai mã HTML khác nhau bên trong bodyvà tiêu đề selectcủa ng-content, giống như sau:

<div #header>This should be rendered in header selection of ng-content</div>
<div #body>This should be rendered in body selection of ng-content</div>

Nhưng thành phần đang hiển thị trống.

Các bạn có biết tôi có thể làm sai điều gì không hoặc cách tốt nhất để hiển thị hai phần khác nhau trong cùng một thành phần là gì?

Cảm ơn!


Xin lỗi, stackoverflow đã không lưu đoạn mã thứ hai của tôi: Mã mà tôi đang sử dụng trong thành phần giống như sau: <div #header> Đây là nội dung tiêu đề </div> <div #body> Đây là nội dung phần thân </div>
Lucas Santos

Câu trả lời:


182
  1. Bạn có thể thêm các thuộc tính giả headerbodytrái ngược với các tham chiếu mẫu (#header, #body).
  2. Và transclude sử dụng ng-contentvới selectthuộc tính như select="[header]".

app.comp.html

<app-child>
    <div header >This should be rendered in header selection of ng-content</div>
    <div body >This should be rendered in body selection of ng-content</div>
</app-child>

child.comp.html

<div class="header-css-class">
    <ng-content select="[header]"></ng-content>
</div>
<div class="body-css-class">
    <ng-content select="[body]"></ng-content>
</div>

BẢN GIỚI THIỆU


6
Nếu bạn không muốn làm thêm div hoặc bất kỳ thẻ khác mà bạn nên sử dụng <ng-container>
sobczi

3
@AmitChigadani Tôi tin rằng @sobczi có nghĩa là bạn có thể thay thế <div header>bằng <ng-container header>.
user12893298320392

3
Tôi xác nhận thay thế <div header>bằng <ng-container header>các công trình quá.
azerafati

49

Để phù hợp với các thông số kỹ thuật của Thành phần Web . Ngay cả khi đó là Angular. Đó là về việc tránh các thuộc tính cho bộ chọn như chỉ thị Angular hoặc các thuộc tính dành riêng với mục đích sử dụng khác. Vì vậy, chúng tôi chỉ sử dụng thuộc tính "slot". Chúng tôi sẽ xem <ng-content select="[slot=foobar]">như <slot name="foobar">.

Thí dụ:

hello-world.component.html

<ng-content select="[slot=start]"></ng-content>
<span>Hello World</span>
<ng-content select="[slot=end]"></ng-content>

app.component.html

<app-hello-world>
  <span slot="start">This is a </span>
  <span slot="end"> example.</span>
</app-hello-world>

Kết quả

This is a Hello World example.

Ví dụ về Stackblitz

Bạn có thể sử dụng bất kỳ tên nào bạn muốn như "chuối" hoặc "cá". Nhưng "start" và "end" là một quy ước tốt để đặt các phần tử trước và sau.


Làm cách nào để truy vấn những yếu tố đó? với khe tên.
Nexeuz

Nó phụ thuộc vào cài đặt Angular và thành phần của bạn và những gì bạn muốn chính xác. Bạn có thể sử dụng ViewChild trong TS hoặc :host::ng-deeptrong SCSS. Nhưng đây chỉ là một ví dụ. Xem Stackblitz Có thể ::slotted/ ::contentcũng sẽ hoạt động. Nhưng không chắc chắn. Trang web sẽ cung cấp thêm về chủ đề này. Nói chung, bạn chỉ nên tạo kiểu cho chính thành phần. Và tránh tạo kiểu bên ngoài (toàn cầu). Nếu không, bạn sẽ có những tác dụng phụ không mong muốn.
Dominik

Một thực hành tốt là quấn nó. Xem ví dụ về Stackblitz được cập nhật trong nhận xét cuối cùng của tôi. Xem tệp html và css của thành phần. Bạn nên thích điều này hơn ng-deep. Vd: <div class="end"><ng-content></ng-content></div>Vì phần tử này có thể truy cập được trong thành phần. Nội dung ng chỉ là một phần tử giả được thay thế bằng phần tử được gắn bên ngoài. Vì vậy, bạn phải sử dụng bộ chọn ng-deep.
Dominik

9

hoặc bạn có thể sử dụng:

app.comp.html

<app-child>
    <div role="header">This should be rendered in header selection of ng-content</div>
    <div role="body">This should be rendered in body selection of ng-content</div>
</app-child>

child.comp.html

<div class="header-css-class">
    <ng-content select="div[role=header]"></ng-content>
</div>
<div class="body-css-class">
    <ng-content select="div[role=body]"></ng-content>
</div>

4

Bổ sung các câu trả lời khác:

Bạn cũng có thể làm điều đó với các thẻ tùy chỉnh (như <ion-card>, <ion-card-header><ion-card-content>).

app.comp.html

<app-child>
    <app-child-header>This should be rendered in header selection of ng-content</app-child-header>
    <app-child-content>This should be rendered in content selection of ng-content</app-child-content>
</app-child>

child.comp.html

<div class="header-css-class">
    <ng-content select="app-child-header"></ng-content>
</div>
<div class="content-css-class">
    <ng-content select="app-child-content"></ng-content>
</div>

Bạn sẽ nhận được một thông báo cảnh báo, nhưng nó sẽ hoạt động. Bạn có thể chặn các thông báo cảnh báo hoặc sử dụng các thẻ đã biết như headerhoặc footer. Tuy nhiên, nếu bạn không thích bất kỳ phương pháp nào trong số này, bạn nên sử dụng một trong các giải pháp khác.

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.