หลายเนื้อหา


104

ฉันกำลังพยายามสร้างส่วนประกอบที่กำหนดเองโดยใช้หลาย ๆ ตัวng-contentใน Angular 6 แต่มันใช้ไม่ได้และฉันไม่รู้ว่าทำไม

นี่คือรหัสส่วนประกอบของฉัน:

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

ฉันกำลังพยายามใช้ส่วนประกอบนี้ในที่อื่นและแสดงโค้ด HTML ที่แตกต่างกันสองรายการภายในbodyและส่วนหัวselectของng-contentสิ่งนี้:

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

แต่คอมโพเนนต์กำลังแสดงผลว่างเปล่า

พวกคุณรู้ไหมว่าฉันทำอะไรผิดหรืออะไรคือวิธีที่ดีที่สุดในการแสดงสองส่วนที่แตกต่างกันในองค์ประกอบเดียวกัน

ขอบคุณ!


ขออภัย stackoverflow ไม่ได้บันทึกข้อมูลโค้ดที่สองของฉัน: โค้ดที่ฉันใช้ในคอมโพเนนต์มีลักษณะดังนี้: <div #header> นี่คือเนื้อหาส่วนหัว </div> <div #body> นี่คือเนื้อหาของเนื้อหา </div>
Lucas Santos

คำตอบ:


194
  1. คุณสามารถเพิ่มหุ่นคุณลักษณะheaderและเมื่อเทียบกับการอ้างอิงแม่แบบbody(#header, #body)
  2. และ transclude ใช้ng-contentกับแอตทริบิวต์เช่นselectselect="[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>

การสาธิต


7
หากคุณไม่ต้องการแสดง div เพิ่มเติมหรือแท็กอื่น ๆ คุณควรใช้ <ng-container>
sobczi

3
@AmitChigadani ผมเชื่อว่า @sobczi นั่นหมายความว่าคุณสามารถแทนที่ด้วย<div header> <ng-container header>
user12893298320392

4
ฉันยืนยันว่าจะแทนที่<div header>ด้วย<ng-container header>ผลงานด้วย
azerafati

51

เพื่อให้เหมาะสมกับข้อกำหนดของWeb Component แม้ว่าจะเป็น Angular ก็ตาม เกี่ยวกับการหลีกเลี่ยงแอตทริบิวต์สำหรับตัวเลือกเช่นคำสั่งเชิงมุมหรือแอตทริบิวต์ที่สงวนไว้ด้วยการใช้งานอื่น ดังนั้นเราจึงใช้แอตทริบิวต์ "slot" เราจะเห็นเป็น<ng-content select="[slot=foobar]"><slot name="foobar">

ตัวอย่าง:

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>

ผลลัพธ์

This is a Hello World example.

ตัวอย่าง Stackblitz

คุณจะใช้ชื่ออะไรก็ได้เช่น "กล้วย" หรือ "ปลา" แต่ "เริ่ม" และ "สิ้นสุด" เป็นแบบแผนที่ดีในการวางองค์ประกอบก่อนและหลัง


ฉันจะสอบถามองค์ประกอบเหล่านั้นได้อย่างไร พร้อมช่องใส่ชื่อ
Nexeuz

ขึ้นอยู่กับการตั้งค่าเชิงมุมและส่วนประกอบของคุณและสิ่งที่คุณต้องการ คุณสามารถใช้ ViewChild ใน TS หรือ:hostและ::ng-deepใน SCSS แต่นี่เป็นเพียงตัวอย่างเท่านั้น ดู Stackblitzอาจจะ::slotted/ ::contentก็ใช้ได้เช่นกัน แต่ไม่แน่ใจ. เว็บจะนำเสนอเพิ่มเติมเกี่ยวกับหัวข้อนี้ โดยทั่วไปคุณควรกำหนดรูปแบบของส่วนประกอบเท่านั้น และหลีกเลี่ยงการจัดแต่งทรงผมภายนอก (ทั่วโลก) มิฉะนั้นคุณจะมีผลข้างเคียงที่ไม่ต้องการ
Dominik

วิธีปฏิบัติที่ดีคือการพันมัน ดูตัวอย่าง Stackblitz ที่อัปเดตในความคิดเห็นล่าสุดของฉัน ดูไฟล์ html และ css ของคอมโพเนนต์ คุณควรชอบสิ่งนี้มากกว่า ng-deep เช่น<div class="end"><ng-content></ng-content></div>เนื่องจากองค์ประกอบนี้สามารถเข้าถึงได้ในคอมโพเนนต์ ng-content เป็นเพียงองค์ประกอบหลอกซึ่งถูกแทนที่ด้วยองค์ประกอบที่เชื่อมต่อด้านนอก ดังนั้นคุณต้องใช้ตัวเลือก ng-deep
Dominik

9

หรือคุณสามารถใช้:

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

เสริมคำตอบอื่น ๆ :

นอกจากนี้คุณยังสามารถทำมันได้ด้วยแท็กที่กำหนดเอง (เช่น<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>

คุณจะได้รับข้อความเตือน แต่จะใช้งานได้ คุณสามารถปราบปรามข้อความเตือนหรือใช้แท็กที่รู้จักกันเช่นหรือheader footerอย่างไรก็ตามหากคุณไม่ชอบวิธีใด ๆ เหล่านี้คุณควรใช้วิธีแก้ปัญหาอื่น ๆ

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