ng-content
是angular的内置指令,用于在 Angular 组件中定义插槽,以便将外部内容插入到组件中显示。它的作用类似于 HTML 中的 <slot>
标签。下面将举例它的几个应用场景:
- 默认插槽:当父组件没有提供内容时,子组件可以显示默认内容。即
<ng-content></ng-content>
所包裹的任何内容。
// child.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<div>
<h2>Child Component</h2>
<ng-content></ng-content> <!-- 显示默认内容 -->
</div>
`
})
export class ChildComponent {}
// parent.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<div>
<h2>Parent Component</h2>
<app-child></app-child> <!-- 没有提供额外内容 -->
</div>
`
})
export class ParentComponent {}
- 具名插槽:父组件可以根据插槽的名称,将内容投影到子组件的特定位置。
// child.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<div>
<h2>Child Component</h2>
<ng-content select="header"></ng-content> <!-- 显示头部内容 -->
<ng-content select="footer"></ng-content> <!-- 显示底部内容 -->
</div>
`
})
export class ChildComponent {}
// parent.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<div>
<h2>Parent Component</h2>
<app-child>
<header>This is the header</header>
<footer>This is the footer</footer>
</app-child>
</div>
`
})
export class ParentComponent {}
- 选择器插槽:父组件可以根据选择器条件,将特定的内容投影到子组件中。
// child.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<div>
<h2>Child Component</h2>
<ng-content select[attr.role=button]></ng-content> <!-- 显示带有 role="button" 属性的元素 -->
</div>
`
})
export class ChildComponent {}
// parent.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<div>
<h2>Parent Component</h2>
<div role="button">Button 1</div>
<div>Not a button</div>
<div role="button">Button 2</div>
<app-child></app-child>
</div>
`
})
export class ParentComponent {}
值得注意的是,ng-content具有一些属性:
- **select**: 用于选择特定的内容进行插入。
- **select.projectAs**: 用于指定插入的内容应该被投影为指定的元素。例如,可以使用 select.projectAs="div"来将插入的内容投影为 `div` 元素。
- **select.attr**: 用于选择带有指定属性的元素进行插入。例如,select[attr.role=button]可以选择带有 role="button"属性的元素进行插入。
- **select.class**: 用于选择带有指定类名的元素进行插入。例如,select.class="special"可以选择带有special类名的元素进行插入。
下面将举例这些属性的示用:
// parent.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<div>
<h2>Parent Component</h2>
<p>This is a paragraph inside the parent component.</p>
<div role="button" class="special">Special button</div>
<app-child>
<p>Default content for child component</p>
<div role="button" class="special">Another special button</div>
</app-child>
</div>
`
})
export class ParentComponent {}
// child.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<div>
<h2>Child Component</h2>
<ng-content select="p"></ng-content> <!-- 插入父组件中的 <p> 元素 -->
<ng-content select[attr.role=button]></ng-content> <!-- 插入带有 role="button" 属性的元素 -->
<ng-content select.class="special"></ng-content> <!-- 插入带有 special 类名的元素 -->
</div>
`
})
export class ChildComponent {}
注意!!!:
在这个例子中,<app-child>`中的 role="button"的 <div>元素也会被投影进去。因为在 app-child组件中,我们使用了ng-content 的 select[attr.role=button]属性来选择带有 role="button"属性的元素进行插入。
所以,无论父组件中有多少个带有 `role="button"` 属性的元素,只要它们被包裹在 `<app-child>` 组件中,它们都会被投影到 `app-child` 组件中的对应位置。