
在 angular 中,组件标签内嵌套的内容默认不会渲染,需通过 `
要让 <app-mat-loading-card> 支持接收并显示内部内容(例如 <span class="button-title">{{device.deviceName}}</span>),你需要在 mat-loading-card 组件的模板中添加 <ng-content> 占位符。
✅ 正确实现步骤
-
修改 mat-loading-card.component.html
在你希望外部内容插入的位置(例如 .child 容器内),加入 <ng-content>:
<div class="main">
<div [ngClass]="{'parent': loading, 'parent-no-anim': !loading}">
<div class="child">
<ng-content></ng-content>
</div>
</div>
</div>? <ng-content> 不是 Angular 组件或指令,而是一个编译时投影插槽——它不会出现在最终 DOM 中,仅作为内容“中转站”,将父组件模板中写在 <app-mat-loading-card>...</app-mat-loading-card> 标签之间的内容,原样渲染到此处。
-
父组件中即可正常使用内容投影
现在以下写法将正常生效:
<app-mat-loading-card [loading]="device.loading || device.connecting">
<span class="button-title">{{ device.deviceName }}</span>
<button (click)="onAction()">Configure</button>
</app-mat-loading-card>渲染结果(当 loading = false 时)将类似:
<div class="main">
<div class="parent-no-anim">
<div class="child">
<span class="button-title">Router-01</span>
<button>Configure</button>
</div>
</div>
</div>⚠️ 注意事项
<ng-content> 不支持绑定事件或输入属性:它只做静态结构投影,无法直接监听子内容中的 (click);如需交互,应通过 @Output() 或服务通信。
-
可使用多插槽投影(带 select 属性)实现更精细控制,例如:
<!-- 子组件模板 --> <header><ng-content select="[slot='header']"></ng-content></header> <main><ng-content select="[slot='body']"></ng-content></main>
对应调用:
<app-mat-loading-card [loading]="true"> <div slot="header"><h3>Loading Device</h3></div> <div slot="body"><span>{{ device.deviceName }}</span></div> </app-mat-loading-card> 投影内容的样式作用域仍受父组件影响(除非启用 ViewEncapsulation.ShadowDom),建议在子组件中为 <ng-content> 包裹容器设置明确类名(如 .child),便于统一控制布局与间距。
✅ 总结
Angular 的内容投影不是“自动继承”,而是“显式接纳”——没有 <ng-content>,所有嵌套内容都会被忽略。掌握 ng-content 是构建高复用 UI 组件(如卡片、模态框、标签页)的必备技能。它让组件既保持封装性,又具备表现力与组合性,真正践行了“关注点分离”与“开放封闭”原则。










