如何使用多个 ng-templates 创建 Angular 6 组件?

How to create Angular 6 component with multiple ng-templates?

我已经阅读了很多关于 Angular 模板的内容,但我没有找到任何与我想要实现的非常相似的东西,更不用说 [=31= 中的模板了] 2+ 令人困惑,这并没有使任务变得比它应该的更容易。

我想知道如何做这样的事情(或者如果可能的话):

<my-form>
  <ng-template [for]="title">Users</ng-template>
  <ng-template [for]="content">
    <form>
      <input type="text" name="username">
      <input type="text" name="password">
    </form>
  </ng-template>
  <ng-template [for]="footer">
    <button (click)="edit()">Edit</button>
    <button (click)="delete()">Delete</button>
  </ng-template>
</my-form>

因此,我的想法是,我的 my-form 组件将包含标记、样式和通用内容,这些内容适用于我想在我的应用程序中创建的所有这些 "common forms"。我一直在谷歌搜索一整天都无济于事,只是为了找到 this article 其中 kinda 类似于我正在尝试做的事情,但它并不接近,而且这篇文章也很难帮我理解。

注意:我什至不知道 [for] 标签是否准确,这超出了我的想象。自定义标签会起作用(例如 <my-form-title></my-form-title><my-form-content></my-form-content><my-form-footer></my-form-footer> 等等)。

这里有人可以帮助我吗?谢谢!

每个 Angular 结构指令将它所附加的元素转换为一个 ng 模板,因此您可以使用自定义指令将 "mark" 个子元素作为模板。

首先,您为组件的可定制部分创建了一堆指令:

@Directive({
  selector: '[myFormTitle]'
})
export class TitleDirective {}

@Directive({
  selector: '[myFormContent]'
})
export class ContentDirective {}

@Directive({
  selector: '[myFormFooter]'
})
export class FooterDirective {}

您使用 @ContentChild 查询组件树以获取由这些指令创建的模板:

@Component({
  selector: 'my-form',
  templateUrl: './my-form.component.html',
})
export class MyFormComponent implements OnInit {
  @ContentChild(TitleDirective, {read: TemplateRef})
  titleTemplate: TemplateRef<any>;

  @ContentChild(ContentDirective, {read: TemplateRef})
  contentTemplate: TemplateRef<any>;

  @ContentChild(FooterDirective, {read: TemplateRef})
  footerTemplate: TemplateRef<any>;

  constructor() { 
  }

  ngOnInit() {
    console.log(this)
  }
}

然后像往常一样在组件模板中渲染它们:

<form>
  <h1>
    <ng-container *ngTemplateOutlet="titleTemplate"></ng-container>
  </h1>
  <hr/>
  <ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
  <hr/>
  <small>
    <ng-container *ngTemplateOutlet="footerTemplate"></ng-container>
  </small>
</form>

你这样使用这个组件:

<my-form>
  <span *myFormTitle>BIG LETTERS</span>
  <div *myFormContent>
    <label>Name: <input name='name'/></label>
  </div>
  <span *myFormFooter>
    yadda blah
  </span>
</my-form>

如果要将上下文传递给模板,还可以在 *myFormTitle 等属性中使用指令 microsyntax;或访问继承的上下文。我不打算在这里深入探讨,因为它并不真正适合您的用例。