Кілька нг-вмісту


95

Я намагаюся створити власний компонент, використовуючи декілька 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>
Лукас Сантос,

Відповіді:


180
  1. Ви можете додати манекен атрибутів headerі bodyна відміну від посилань шаблону (#header, #body).
  2. І виключити використання ng-contentз selectатрибутом like 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>

ДЕМО


6
Якщо ви не хочете відображати додатковий div або будь-який інший тег, вам слід використовувати <ng-container>
sobczi

3
@AmitChigadani Я вважаю, @sobczi мав на увазі, що ви можете замінити <div header>на <ng-container header>.
user12893298320392

3
Я також підтверджую заміну <div header>на <ng-container header>твори.
азерафаті

49

Щоб відповідати специфікаціям веб-компонентів . Навіть якщо це Angular. Йдеться про уникнення атрибутів для селектора, таких як директиви 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.

Приклад стекбліцу

Ви можете використовувати будь-яку назву, яку хочете, як «банан» або «риба». Але "початок" і "кінець" - це хороша умова для розміщення елементів до і після.


Як я можу запитати ці елементи? із слотом імен.
Nexeuz

Це залежить від ваших налаштувань Angular та компонентів та того, що саме ви хочете. Ви можете використовувати ViewChild в TS або :hostі ::ng-deepв SCSS. Але це лише приклад. Дивіться Stackblitz Можливо ::slotted/ ::contentтакож буде працювати. Але не впевнений. Інтернет запропонує більше про цю тему. Як правило, слід стилювати лише сам компонент. І уникайте стилізації речей зовні (глобально). Інакше у вас з’являться небажані побічні ефекти.
Домінік

Хороша практика - це обгортання. Дивіться оновлений приклад Stackblitz в моєму останньому коментарі. Дивіться файл html і css компонента. Ви повинні віддавати перевагу цьому перед нг-глибиною. Наприклад, <div class="end"><ng-content></ng-content></div>оскільки цей елемент доступний у компоненті. Ng-вміст - це просто псевдоелемент, який замінюється стикованим зовні. Тому вам доведеться використовувати селектор ng-deep.
Домінік

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. Однак, якщо вам не подобається жоден із цих методів, вам слід вибрати одне з інших рішень.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.