Угловой 6-кратный нг-контент
Я пытаюсь создать пользовательский компонент, используя несколько NG контента в 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-кода внутри тела и заголовок выбора ng-контента, что-то вроде этого:
<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>
Но компонент отображается пустым. Ребята, вы знаете, что я могу делать неправильно или как лучше всего отобразить два разных раздела в одном компоненте?
Спасибо!
6 ответов
Вы можете добавить фиктивные атрибуты header
а также body
в отличие от ссылок на шаблоны (#header, #body)
и включить с помощью ng-content
,
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>
Чтобы соответствовать спецификациям веб-компонентов. Даже если это Angular. Речь идет об избежании атрибутов для селектора, таких как директивы Angular или зарезервированных атрибутов с другим использованием. Итак, мы просто используем атрибут "слот". Посмотрим<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
Вы можете использовать любое имя, например "банан" или "рыба". Но "начало" и "конец" являются хорошим условием для размещения элементов до и после.
В качестве альтернативы вы можете использовать:
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>
Дополняя другие ответы:
Вы также можете сделать это с помощью пользовательских тегов (например, <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
. Однако, если вам не нравится какой-либо из этих методов, вы должны выбрать одно из других решений.
в качестве другого варианта вы можете передавать шаблоны дочернему компоненту, и тогда у вас будет возможность привязать значения к содержимому / шаблонам.
родительский компонент html <app-child
[templateHeader]="header"
[templateContent]="content>
</app-child>
<ng-template #header
let-data="data"> < -- how you get dynamic data
what ever you would like the header to say
{{data}}
</ng-template>
<ng-template #content>
what ever you would like the content to say or any other component
</ng-template>
дочерний компонент ts
export class ChildComponent {
@Input() templateHeader: TemplateRef<any>;
@Input() templateContent: TemplateRef<any>;
}
дочерний компонент html
<div class="header-css-class">
<ng-container
*ngTemplateOutlet="
templateHeader;
context: { , < -- if you want to pass data to your template
data: data
}">
</ng-container>
</div>
<div class="content-css-class">
<ng-container *ngTemplateOutlet="templateContent">
</ng-container>
</div>
для более полного объяснения шаблонов см. эту замечательную статью https://indepth.dev/posts/1405/ngtemplateoutlet
если вы просто хотите «принять» более одного компонента, вы можете использовать:
<ng-content select="custom-component,a"></ng-content>
Это принимает элементы пользовательского компонента, а также элементы привязки (а) и не меняет последовательность.