问题形容
我应用如下代码测试一个最简略的 Angular 内容投影场景:
import {Component} from '@angular/core';
@Component({
selector: 'app-zippy-basic',
template: `
<h2>Single-slot content projection</h2>
<ng-container></ng-container>
`
})
export class ZippyBasicComponent {}
我冀望 app-zippy-basic
的使用者,将传入的 content
,投射到元素 ng-container
外部。
生产代码如下图所示:
<app-zippy-basic>
<p>Is content projection cool?</p>
<div>ok</div>
</app-zippy-basic>
然而运行时,我在渲染出的页面里,基本看不到 Is content projection cool?
的显示。
问题剖析
关上 Chrome 开发者工具,发现 app-zippy-basic
外部只有一个 comment 节点:ng-container
咱们在提供内容投影插槽的 Component 的 ng-container 之间轻易键入一些字符串,例如 DIV:
渲染后发现,ng-container 没能依照咱们冀望的工作。
通过查阅 Angular 官网,发现这里把 ng-container 和 ng-content 弄混同了。此处应该应用 ng-content.
解决方案
ng-content
之间不容许再插入其余元素。仅仅充当一个占位符的角色。
应用 ng-content
之后问题隐没。这里咱们能够通过单步调试的形式,搞清楚被投影的内容是如何插入到 ng-content 占位符里的。
抉择 app-zippy-basic
,给其设置一个 dom 断点,类型为 subtree modification
:
首先执行 template 函数,将 Component 自身的 h2 元素,进行 HTML 源代码的渲染:
接下来是 Angular 解决整个内容投影逻辑的要害:
遇到 ng-content
,则调用函数 ɵɵprojection
:
转而调用 applyProjection
:
parent node 即是指定义了 ng-content
的 Component 对应的 dom 元素:
rNode 即是被插入到 app-zippy-basic
中的节点,即 app-zippy-basic
的消费者。
生产语法:
<app-zippy-basic>
此处插入你想投影到 app-zippy-basic 外部的 HTML 源代码
</app-zippy-basic>