关于javascript:译angular中的ngtemplate-ngcontent-ngcontainer

5次阅读

共计 3176 个字符,预计需要花费 8 分钟才能阅读完成。

本文会蕴含作者一些了解,为了不和原作者意思混同,会将集体的了解放在【】里。

原文地址

那是我忙于为我的办公我的项目创作新性能的日子之一。忽然间,某些事件引起了我的留神。

上图是 angular 最终渲染进去的 DOM

当我审查 DOM 时候,我看到这个 ngcontent 被 Angular 利用到了元素上。如果他们蕴含元素在最终的 DOM 里,那么 <ng-container> 是用来干什么的?那是我很困惑在 <ng-container><ng-content>中。

在探寻问题答案的时候我发现了 <ng-template>*ngTemplateOutlet的概念。当初咱们有四个听起来简直雷同的概念。我开始了探寻它们的旅程。

你已经也遇到过这种状况吗?如果是,那么你来对中央了。闲话少说,让咱们一个一个来解说他们。

1. < ng-template >

顾名思义,<ng-template> 是一个模板元素,用于 Angular 与构造指令联合应用 (*ngIf, *ngFor, [ngSwitch] 和自定义指令)

<font color=’red’> 这些模板元素仅工作在构造指令存在的时候 </font>。Angular 包装了咱们利用指令的元素。思考下边的一个 *ngIf 的例子。

【咱们能够看到,在一个一般元素上增加构造指令,angular 在解析时候,其实会帮我买创立一个 ng-template 元素,并将相干的构造指令放到 ng-template 上进行解决】

下面展现的是 Angular 对与 *ngIf 的解释。最终的 DOM 与咱们在本文结尾看到的相似。

应用办法

咱们曾经看到了 Angular 应用 <ng-template> 的形式。然而咱们如何应用它呢?因为它只和构造指令一起工作,所以咱们能够这样应用:【这种是❌形式,后边会讲到】

此处的 home 设置为 true,上述代码在 DOM 中的输入为:

什么都没有被渲染进去!这是为什么呢?其实,这正是预期的后果。正如咱们曾经探讨过的,Angular 会用正文代替ng-template【译文应用的 Angular 版本为 6.1.10。在 Angular12 版本,曾经用非凡的 className 代替正文了】,咱们的代码最终会被解释成如下代码。

咱们的 <ng-template> 在被 Angular 包装之后,变成了两个。然而无论怎样,Angular 都不对 <ng-template> 的内容进行选中。

以下是两种 <font color=green> 正确 </font> 的应用形式:

Method 1

在第一种办法中,你提供给 Angular 一种不须要进一步解决的形式。这样 Angular 将仅仅转换 <ng-template> 到正文里,并不会扭转其内容。(它们不会再像之前的例子一样被放在任何 <ng-template> 中)。因而,它将正确的渲染内容。

要想理解更多如何应用此构造和更多的构造指令,请参考这篇文章。

Method2

这是一种很少应用的形式(应用两个<ng-template>)。这里咱们在 then 中给出了一个模板援用,通知他当条件为真时候应该渲染什么。

像这样应用多 <ng-template>(你能够应用<ng-container> 代替)是不被倡议的因为这不是 Angular 的本意。<ng-template>该当被应用在多处重复使用的场景下。咱们将在文章前面的局部更具体的探讨。

< ng-container >

你是否已经写过或看到过相似这样的代码

咱们大部分人写这样代码的起因在于 Angular 无奈再单个元素上应用多个构造指令。当初这个代码失常工作,然而如果 item.id 为 false,它就会在 dom 中引入很多空的<div>

在简略的例子中可能不须要关怀它,但如果在大型简单的利用中时候(会展现成千上万的数据),它可能变得麻烦,因为有可能会有监听器在这些 DOM 上。

更蹩脚的是你可能必须去嵌套你的 CSS。【大略是想表白这些写会在附加款式时候须要额定的选择器】

不要放心!咱们有 <ng-container> 能够解决。

<ng-container>是一个组元素,它不会烦扰款式或布局,因为 Angular 不会将它们渲染到 DOM 中。

以上代码会渲染出这样的 DOM 构造

看,咱们解脱了那些空的 div。咱们应该应用 <ng-container> 当咱们仅仅想应用多个构造指令而不想引入多的 DOM 时候。

3、< ng-content >

它用于创立可配置的组件。这意味着组件能够依据用户的志愿来配置。这就是家喻户晓的内容投影~

思考一个简略的应用了 <ng-content> 的组件

<project-content> 组件的开始标记和完结标记之间是将要被内容投影的内容。【也就是 vue 和 react 的 slot】

这些内容将被渲染在组件的 <ng-content> 中,这将容许自定义 <project-content> 组件的页脚局部。

多重投影

如果你能够决定哪些内容能够被渲染到哪些地方会怎么?您还能够应用 <ng-content> 的 select 属性来管制内容的投影形式,而不是在单个的 <ng-content> 中投影每个内容。它须要一个元素选择器来决定特定的 <ng-content> 中投影哪些内容.

办法如下:

咱们批改 <project-content> 来演示如何应用多内容投影。Select 属性选择器将在特定的 <ng-content> 中出现的内容。这里咱们首先抉择出现 h1 元素,如果投射的内容中没有 h1 元素,它将不会渲染任何内容。同样,第二个抉择查找 div。其余的内容在最初一个 <ng-content> 中出现。

以上的形式应该是老版本的 Angular 了,当初的 Angular 文档中没有提到,当初的应用形式请查看最新文档

4、*ngTemplateOutlet

*ngTemplateOutlet 个别被用在两个场景:

  1. 不管循环或条件如何,在视图中插入一个公共模板
  2. 创立一个高度配置的组件

模版重用

思考一个视图,其必须在多个地位插入模板。例如,要搁置在网站中的公司 logo。咱们能够通过为 logo 编写一次模板并在视图的任何中央重用来实现它。

上面是代码片段:

正如你看到的,咱们只写了一次模板代码,并应用了它三次!

<*ngTemplateOutlet> 也承受一个上下文对象,能够传递改对象来自定义通用模板输入。无关上下文的更多信息,请参阅官网文档

自定义组件

<*ngTemplateOutlet> 的第二个应用形式是高度订制组件。思考咱们之前的<project-content> 的示例。并进行一些批改。

下面是<project-content> 组件的批改版本,它承受三个属性 —— <headerTemplate> <bodyTemplate> <footerTemplate>。上面是其代码片段:

咱们在这里视图实现的是显示从 <project-content> 的父组件承受到的页眉,注释和页脚。如果其中任何一个未提供,咱们的组件在其地位展现默认模版。因而,创立了一个高度订制的组件。

当初应用咱们刚创立的组件:

这是咱们如何传递一个 template refs 给咱们的组件的形式。如果其中任何一个没有传递,组件将渲染默认的模板!

ng-content vs *ngTemplateOutlet

它们都帮咱们实现了高度自定义的组件,然而咱们该如何抉择它们呢?

能够革除的看到,*ngTemplateOutlet给了咱们更多的能力,例如提供默认的模板 …

<ng-content> 智能依照原样出现内容,借助 select 属性,您能够拆分内容并在视图的不同地位出现它们。您不能有条件的出现 <ng-content> 的内容。您必须限度从父组件哪里承受到的内容,而无奈依据内容做出决定。

无论如何,在这两个间进行抉择齐全取决于你的用例。至多当初咱们有了一个新的武器 *ngTemplateOutlet,它提供了更多的控制权比照<ng-content>

正文完
 0