Angular:将模板传递给子组件的最佳/推荐方法

Mar*_*yna 10 parent-child ng-template angular

我想知道最好或推荐的方法是将模板传递给子组件。据我所知,基本上有 3 种方法可以做到这一点:

选项1

父级.html

<ng-template #mytemplate>
  <!-- some stuff -->
</ng-template>

<child [stuff]="myTemplate"></child>
Run Code Online (Sandbox Code Playgroud)

孩子.ts

@Input() public stuff: TemplateRef<any>;
Run Code Online (Sandbox Code Playgroud)

孩子.html

<ng-container [ngTemplateOutlet]="stuff"></ng-container>
Run Code Online (Sandbox Code Playgroud)

选项2

父级.html

<child>
  <ng-template #mytemplate>
    <!-- some stuff -->
  </ng-template>
</child>
Run Code Online (Sandbox Code Playgroud)

孩子.ts

@ContentChild(TemplateRef) layoutTemplate: TemplateRef<any>;
Run Code Online (Sandbox Code Playgroud)

孩子.html

<ng-container *ngTemplateOutlet="layoutTemplate">
</ng-container>
Run Code Online (Sandbox Code Playgroud)

选项3

父级.html

<child>
  <!-- some stuff -> not ng-template around it! -->
</child>
Run Code Online (Sandbox Code Playgroud)

孩子.ts

// nothing required
Run Code Online (Sandbox Code Playgroud)

孩子.html

<ng-content></ng-content>
Run Code Online (Sandbox Code Playgroud)

我无法在文档中找到有关“标准”方式的任何内容。仅仅是味道吗?其中之一是否有好处使其成为默认方式?

当然,总有一些用例其中一种更适合。但我对上面的例子感兴趣 - 所有这些都可以使用。

是否已经在某处给出了一些文档或建议?看来您在搜索“如何将模板传递给子项”时找到的示例更有可能使用选项 2。但是为什么呢?我猜这是因为他们倾向于展示案例示例,其中模板不仅用于将其传递给子项,而且还用于父项本身。

谢谢!

Ath*_*ras 1

一如既往,不同的工具适合不同的事情

内容投影

如果 html 代码需要内联,请使用内容投影 ( ng-content )。考虑在特定库或某种选项卡解决方案中使用自定义下拉列表。如果你有以下内容,它会使代码不优雅且可读性较差:

<fantasy-tabs>
   <fantasy-tab [tabContent]="myTemplate">
   <fantasy-tab [tabContent]="myTemplate2">
   <fantasy-tab [tabContent]="myTemplate3">
</fantasy-tabs>
Run Code Online (Sandbox Code Playgroud)

想象一下上面的内容,在一个复杂的 html 中,以及在 html 末尾或开头声明的模板。

出于这个原因,内容投影主要在库中使用(它可以像往常一样用作 html),并且当内容没有条件时(下面进一步解释)。

在很长一段时间里,这也是唯一的选择。

模板出口

第一个和第二个解决方案几乎相同。您正在使用ngTemplateOutlet. 这几乎适用于任何其他用途,并且是首选,特别是当您有隐藏/取消隐藏内容的特殊情况时。

问题是 ng-content 总是会创建子组件,即使ngIf它与父组件一起销毁。所以最好使用ngTemplateOutlet

请在此处查看这篇文章以获取更多信息

内容儿童

@ContentChild查询 dom 以获取本地内容、指令等的第一个。它用于查询元素,因此,我预计它应该会影响性能(但使您可以在输入不够时使用)。

话又说回来,您无法使用您正在搜索的任何指令查询 dom 来获取第一个元素。

一个用法的例子是,如果您的组件中有一个位置您希望在列表中显示 dom 的突出显示(突出显示指令)的项目。然后你就可以用来@ContentChildren获取它们了。