• 投影

    投影

    投影是Angular 2中非常重要的概念。它使开发人员能够构建可重用的组件,并使应用程序更具可扩展性和可维护性。为了说明,假设我们有一个ChildComponent这样的:

    1. @Component({
    2. selector: 'child',
    3. template: `
    4. <div>
    5. <h4>Child Component</h4>
    6. {{ childContent }}
    7. </div>
    8. `
    9. })
    10. export class ChildComponent {
    11. childContent: string = "Default content";
    12. }

    如果我们要将{{childContent}}替换为提供给ChildComponent的任何HTML,我们应该怎么办? 一个诱人的想法是定义一个包含文本的@Input,但如果你想提供样式化的HTML或其他组件呢? 尝试使用@Input处理这个问题可能会很快弄乱,这是内容投影的地方。组件默认情况下支持投影,您可以使用ngContent指令将投影内容放置在模板中。

    因此,改变ChildComponent使用投影:

    app/child/child.component.ts

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'rio-child',
    4. template: `
    5. <div style="border: 1px solid blue; padding: 1rem;">
    6. <h4>Child Component</h4>
    7. <ng-content></ng-content>
    8. </div>
    9. `
    10. })
    11. export class ChildComponent {
    12. }

    然后,当我们在模板中使用ChildComponent时:

    app/app.component.html

    1. ...
    2. <rio-child>
    3. <p>My <i>projected</i> content.</p>
    4. </rio-child>
    5. ...

    这告诉Angular,对于<rio-child>的开始和结束标记之间出现的任何标记,放置在<ng-content></ng-content>内。
    当这样做,我们可以有其他组件,标记等投影在这里和ChildComponent不需要知道或关心提供什么。

    查看示例

    但是,如果我们有多个<ng-content></ng-content>,并希望指定预计的内容一定的位置ng-content?例如,对于前面的ChildComponent,如果我们想投影内容转换成一个额外的格式化header和footer部分:

    1. import {Component, Input} from '@angular/core';
    2. @Component({
    3. selector: 'child',
    4. template: `
    5. <h4>Child Component</h4>
    6. <ng-content select="header"></ng-content>
    7. <ng-content></ng-content>
    8. <ng-content select="footer"></ng-content>
    9. `
    10. })
    11. class ChildComponent {}

    然后在模板中,我们可以使用指令,例如<header>,通过select =“header”指定投影内容到ng-content的位置:

    app/app.component.html

    1. ...
    2. <rio-child-select>
    3. <section>Section Content</section>
    4. <div class="class-select">
    5. div with .class-select
    6. </div>
    7. <footer>Footer Content</footer>
    8. <header>Header Content</header>
    9. </rio-child-select>
    10. ...

    除了使用指令,开发人员还可以通过css类选择 ng-content

    1. <ng-content select=".class-select"></ng-content>

    app/app.component.html

    1. <div class="class-select">
    2. div with .class-select
    3. </div>

    View Example