Нг-контейнер напечатан вне контейнера
Я создаю пользовательский модальный компонент (я хотел что-то простое), и я нашел такое поведение, которое я не могу понять.
Это мой модальный компонент HTML
<div class="modal-overlay">
<div class="modal-main">
<ng-content selector="header"></ng-content>
<ng-content></ng-content>
<ng-content selector="footer"></ng-content>
</div>
</div>
Если я использую этот шаблон компонента, все будет работать нормально, позже я смогу использовать этот компонент, как показано ниже, и будет работать так, как указано.
<app-modal>
<header><h1>Hello modal!</h1></header>
<div class="modal-content">This is a modal that will be printed nicely</div>
<footer><button>Close</button></footer>
</app-modal>
Проблема возникает, когда я пытаюсь инкапсулировать один из ng-content
внутри див. Если я сделаю
<div class="modal-overlay">
<div class="modal-main">
<div class="is-flex">
<ng-content selector="header"></ng-content>
<i class="fas fa-times"></i>
</div>
<ng-content></ng-content>
<ng-content selector="footer"></ng-content>
</div>
</div>
Полученный HTML будет следующим.
<div _ngcontent-c1="" class="modal-overlay">
<div _ngcontent-c1="" class="modal-main">
<div _ngcontent-c1="" class="is-flex">
<i class="fas fa-times"></i>
</div>
<header><h1>Hello modal!</h1></header>
<div class="modal-content">This is a modal that will be printed nicely</div>
<footer><button>Close</button></footer>
</div>
</div>
Любые идеи, почему header
не заканчивается внутри .is-flex
DIV? Спасибо!
1 ответ
ng-content не "производит" контент, он просто проецирует существующий контент. Думайте об этом как о некоторой вариации node.appendChild(el) или хорошо известной JQuery-версии $(node).append(el): с этими методами узел не клонируется, он просто перемещается на новое место. Из-за этого жизненный цикл проецируемого контента связан с тем, где он объявлен, а не с тем, где он отображается.
Используйте нг-шаблон
<app-modal>
<ng-template> <header><h1>Hello modal!
</h1></header></ng-template>
<div class="modal-content">This is a modal that will be printed nicely</div>
<footer><button>Close</button></footer>
</app-modal>
так как он получает шаблон. Он должен получить доступ к шаблону с помощью @ContentChild и использовать ngTemplateOutlet для его отображения.
<div class="modal-overlay">
<div class="modal-main">
<div class="is-flex">
<ng-container
[ngTemplateOutlet]="template">
</ng-container>
<i class="fas fa-times">
</i>
</div>
<ng-content></ng-content>
<ng-content selector="footer">
</ng-content>
</div>
</div>
@ContentChild(TemplateRef) template: TemplateRef
Для получения дополнительной информации: https://medium.com/claritydesignsystem/ng-content-the-hidden-docs-96a29d70d11b