Maison > interface Web > js tutoriel > Parlons de la méthode de projection de contenu en angulaire

Parlons de la méthode de projection de contenu en angulaire

青灯夜游
Libérer: 2022-05-12 10:41:28
original
2230 Les gens l'ont consulté

Cet article parlera de la projection de contenu dans angular, présentera la méthode d'utilisation de ng-content pour la projection de contenu et comprendra la méthode de mise en œuvre de la projection de contenu conditionnelle. J'espère que cela sera utile à tout le monde !

Parlons de la méthode de projection de contenu en angulaire

1. ng-content pour la projection de contenu

ng-content 进行内容投影

1.1 <span style="font-size: 16px;">ng-content</span>

ng-content 元素是一个用来插入外部或者动态内容的占位符。父组件将外部内容传递给子组件,当 Angular 解析模板时,就会在子组件模板中 ng-content 出现的地方插入外部内容。【相关教程推荐:《angular教程》】

我们可以使用内容投影来创建可重用的组件。这些组件有相似的逻辑和布局,并且可以在许多地方使用。一般我们在封装一些公共组件的时候经常会用到。

1.2 为什么使用内容投影

定义一个 button 组件:

button-component.ts

@Component({
    selector: &#39;[appButton]&#39;,
    template: `
    <span class="icon-search"></span>
`
})
export class AppButtonComponent {}
Copier après la connexion

这个 button 组件的目的是在按钮内部加一个搜索的图标,我们实际使用如下:

<button appButton>click</button>
Copier après la connexion
Copier après la connexion

我们发现组件只会展示搜索图标, 按钮的文本不会展示,能你会想到最常使用的 @Input 装饰器,但是如果我们不只是想传文本进来,而是传一段 html 进来呢?此时就会用到 ng-content

1.3 单插槽内容投影

内容投影的最基本形式是单插槽内容投影

单插槽内容投影是指创建一个组件,我们可以在其中投影一个组件。

以 button 组件为例,创建一个单槽内容投影:

button-component.ts

@Component({
    selector: &#39;[appButton]&#39;,
    template: `
    <span class="icon-search"></span> <ng-content></ng-content>
`
})
export class AppButtonComponent {}
Copier après la connexion

实际使用如下:

<button appButton>click</button>
Copier après la connexion
Copier après la connexion

可以发现,现在这个 button 组件的效果是即显示了搜索图标,又显示了按钮的文本(click)。即把 <button appButton></button> 中间的内容 投影 到了组件的 <ng-content></ng-content> 位置。

ng-content 元素是一个占位符,它不会创建真正的 DOM 元素。ng-content 的那些自定义属性将被忽略。

1.4 多插槽内容投影

一个组件可以具有多个插槽,每个插槽可以指定一个 CSS 选择器,该选择器会决定将哪些内容放入该插槽。该模式称为多插槽内容投影。使用此模式,我们必须指定希望投影内容出现在的位置。可以通过使用 ng-contentselect 属性来完成此任务。

  • 组件模板含有多个 ng-content 标签。
  • 为了区分投影的内容可以投影到对应 ng-content 标签,需要使用 ng-content 标签上的 select 属性作为识别。
  • select 属性支持标签名属性CSS 类 :not 伪类的任意组合。
  • 不添加 select 属性的 ng-content 标签将作为默认插槽。所有未匹配的投影内容都会投影在该 ng-content 的位置。

以 button 组件为例,创建一个多槽内容投影:

button-component.ts

@Component({
    selector: &#39;[appButton]&#39;,
    template: `
    <span class="icon-search"></span> <ng-content select="[shuxing]"></ng-content> <ng-content select="p"></ng-content> <ng-content select=".lei"></ng-content>
`
})
export class AppButtonComponent {}
Copier après la connexion

实际使用如下:

<button appButton>
<p>click</p> <span shuxing>me</span> <span class="lei">here</span>
</button>
Copier après la connexion

1.5 <span style="font-size: 16px;">ngProjectAs</span>

在某些情况下,我们需要使用 ng-container 把一些内容包裹起来传递到组件中。大多数情况是因为我们需要使用结构型指令像 ngIf 或者 ngSwitch 等。。

在下面的例子中,我们将 header 包裹在了 ng-container 中。

@Component({
    selector: &#39;app-card&#39;,
    template: `
		<div class="card">
		  <div class="header">
		    <ng-content select="header"></ng-content>
		  </div>
		  <div class="content">
		    <ng-content select="content"></ng-content>
		  </div>
		  <div class="footer">
		    <ng-content select="footer"></ng-content>
		  </div>
		  <ng-content></ng-content>
		</div>
`
})
export class AppCardComponent {}
Copier après la connexion

使用:

<app-card>
  <ng-container>
    <header>
      <h1>Angular</h1>
    </header>
  </ng-container>
  <content>One framework. Mobile & desktop.</content>
  <footer><b>Super-powered by Google </b></footer>
</app-card>
Copier après la connexion

由于 ng-container 的存在,header 部分并没有被渲染到我们想要渲染的插槽中,而是渲染到了没有提供任何 selectorng-content 中。
在这种情况下,我们可以使用 ngProjectAs 属性。
在上面的 ng-container

1.1 < code><span style="font-size: 16px;">ng-content</span>🎜🎜L'élément ng-content est utilisé pour insérer un élément externe ou < code>Espace réservé pour le contenu dynamique. Le composant parent transmet le contenu externe au composant enfant. Lorsque Angular analyse le modèle, il apparaîtra dans le modèle du composant enfant où ng-content. apparaît. Insérer du contenu externe. [Recommandation de didacticiel connexe : "🎜tutoriel angulaire🎜"]🎜🎜Nous pouvons utiliser la projection de contenu pour créer des composants réutilisables. Ces composants ont une logique et une disposition similaires et peuvent être utilisés dans de nombreux endroits. Généralement, nous l'utilisons souvent pour encapsuler certains composants publics. 🎜🎜🎜1.2 Pourquoi utiliser la projection de contenu🎜🎜Définir un composant bouton : 🎜🎜button-component.ts 🎜
<app-card>
  <ng-container ngProjectAs=&#39;header&#39;>
    <header>
      <h1>Angular</h1>
    </header>
  </ng-container>
  <content>One framework. Mobile & desktop.</content>
  <footer><b>Super-powered by Google </b></footer>
</app-card>
Copier après la connexion
Copier après la connexion
🎜Le but de ce composant de bouton est d'ajouter une icône de recherche à l'intérieur du bouton. Nous l'utilisons en fait comme suit : 🎜
<div>
  <ng-container>
    <p>My name is wyl.</p>
    <p>What is you name?</p>
  </ng-container>
</div>
Copier après la connexion
Copier après la connexion
🎜Nous avons constaté que le composant n'affichera que l'icône de recherche et que le texte du bouton ne le sera pas. affiché. Vous penserez au décorateur @Input le plus couramment utilisé, mais que se passe-t-il si nous ne voulons pas simplement transmettre du texte, mais un morceau de html ? ng-content sera utilisé à ce moment. 🎜🎜🎜1.3 Projection de contenu à emplacement unique🎜🎜La forme la plus basique de projection de contenu est la Projection de contenu à emplacement unique</ code >. 🎜<blockquote>🎜La projection de contenu à emplacement unique signifie créer un composant dans lequel nous pouvons projeter un composant. 🎜</blockquote>🎜Prenez le composant bouton comme exemple pour créer une projection de contenu à emplacement unique : 🎜🎜<code>button-component.ts🎜
<div>
  <p>My name is wyl.</p>
  <p>What is you name?</p>
</div>
Copier après la connexion
Copier après la connexion
🎜L'utilisation réelle est la suivante : 🎜
<ul>
  <ng-container *ngFor="let item of items">
    <li>{{ item .name}}</li>
    <li>{{ item .age}}</li>
    <li>{{ item .sex}}</li>
  </ng-container>
</ul>
Copier après la connexion
Copier après la connexion
🎜Vous peut trouver que maintenant le composant bouton L'effet est que l'icône de recherche et le texte du bouton (clic) sont affichés. Autrement dit, le contenu au milieu de <button appButton></button> est projeté sur le <ng-content></ du composant. ng-content>< /code> emplacement. 🎜<blockquote>🎜ng-content est un espace réservé, il ne crée pas un véritable élément DOM. Ces propriétés personnalisées de ng-content seront ignorées. 🎜</blockquote>🎜🎜<span style="font-size: 16px;">1.4 Projection de contenu multi-slot</span></strong>🎜🎜Un composant peut avoir <code>plusieurs emplacements</code >, chaque emplacement peut spécifier un <code>sélecteur CSS qui détermine le contenu qui entre dans cet emplacement. Ce mode est appelé Projection de contenu multi-slot. En utilisant ce mode, nous devons spécifier où nous voulons que le contenu projeté apparaisse. Cela peut être accompli en utilisant l'attribut select de ng-content. 🎜
  • Le modèle de composant contient des balises plusieurs ng-content.
  • Afin de distinguer le contenu projeté qui peut être projeté sur la balise ng-content correspondante, vous devez utiliser select</code sur le <code>ng -content tag > Attributs comme identifiants.
  • L'attribut select prend en charge le nom de la balise, la propriété, la classe CSS et : Toute combinaison de non-pseudo-classes. Les balises
  • ng-content sans ajouter l'attribut select serviront d'emplacement par défaut. Tout le contenu projeté sans correspondance sera projeté à cet emplacement ng-content.
🎜Prenons le composant bouton comme exemple pour créer une projection de contenu multi-slot : 🎜🎜button-component.ts🎜
<ng-template>
    <p> In template, no attributes. </p>
</ng-template>

<ng-container>
    <p> In ng-container, no attributes. </p>
</ng-container>
Copier après la connexion
Copier après la connexion
🎜L'utilisation réelle est la suivante : 🎜
In ng-container, no attributes.
Copier après la connexion
Copier après la connexion
🎜🎜1.5 <span style="font-size: 16px;">ngProjectAs</span> 🎜🎜Dans certains cas, nous devons ensuite utiliser ng-container pour envelopper du contenu et le transmettre au composant. La plupart du temps, c'est parce que nous devons utiliser des directives structurelles comme ngIf ou ngSwitch etc. . 🎜🎜Dans l'exemple ci-dessous, nous enveloppons header dans ng-container. 🎜
<ng-template [ngIf]="true">
   <p> ngIf with a ng-template.</p>
</ng-template>

<ng-container *ngIf="true">
   <p> ngIf with an ng-container.</p>
</ng-container>
Copier après la connexion
Copier après la connexion
🎜Utilisation : 🎜
ngIf with a ng-template.
ngIf with an ng-container.
Copier après la connexion
Copier après la connexion
🎜En raison de l'existence de ng-container, la partie header n'est pas rendue dans l'emplacement que nous voulons restituer, mais est rendue dans non Fournissez n'importe quel sélecteur dans ng-content.
Dans ce cas nous pouvons utiliser l'attribut ngProjectAs.
L'ajout de cet attribut au ng-container ci-dessus le rendra comme prévu. 🎜
<app-card>
  <ng-container ngProjectAs=&#39;header&#39;>
    <header>
      <h1>Angular</h1>
    </header>
  </ng-container>
  <content>One framework. Mobile & desktop.</content>
  <footer><b>Super-powered by Google </b></footer>
</app-card>
Copier après la connexion
Copier après la connexion

二、 有条件的内容投影

如果你的元件需要有条件地渲染内容或多次渲染内容,则应配置该元件以接受一个 ng-template 元素,其中包含要有条件渲染的内容。

在这种情况下,不建议使用 ng-content 元素,因为只要元件的使用者提供了内容,即使该元件从未定义 ng-content 元素或该 ng-content 元素位于 ngIf 语句的内部,该内容也总会被初始化。

使用 ng-template 元素,你可以让元件根据你想要的任何条件显式渲染内容,并可以进行多次渲染。在显式渲染 ng-template 元素之前,Angular 不会初始化该元素的内容。

2.1 <span style="font-size: 16px;">ng-container</span>

既不是一个组件,也不是一个指令,仅仅是一个特殊的tag而已。 使用 ng-container 渲染所包含的模板内容,不包含自身。

  • angular代码片段
<div>
  <ng-container>
    <p>My name is wyl.</p>
    <p>What is you name?</p>
  </ng-container>
</div>
Copier après la connexion
Copier après la connexion
  • 浏览器调试窗口,可以发现 <ng-container> 标签消失了,并没有起任何作用
<div>
  <p>My name is wyl.</p>
  <p>What is you name?</p>
</div>
Copier après la connexion
Copier après la connexion
  • 使用场景,如下,在我们需要遍历if 判断 时,它可以承担一个载体的作用
<ul>
  <ng-container *ngFor="let item of items">
    <li>{{ item .name}}</li>
    <li>{{ item .age}}</li>
    <li>{{ item .sex}}</li>
  </ng-container>
</ul>
Copier après la connexion
Copier après la connexion

另外,ng 中常见错误之一的 forif 不能写在同一标签上(在一个宿主元素上只能应用一个结构型指令),利用 ng-container 标签可以在实现功能的基础上减少层级的嵌套。

2.2 <span style="font-size: 16px;">ng-template</span>

先来看下面一段代码

<ng-template>
    <p> In template, no attributes. </p>
</ng-template>

<ng-container>
    <p> In ng-container, no attributes. </p>
</ng-container>
Copier après la connexion
Copier après la connexion

浏览器输出结果是:

In ng-container, no attributes.
Copier après la connexion
Copier après la connexion

<ng-template> 中的内容不会显示。当在上面的模板中添加 ngIf 指令:

<ng-template [ngIf]="true">
   <p> ngIf with a ng-template.</p>
</ng-template>

<ng-container *ngIf="true">
   <p> ngIf with an ng-container.</p>
</ng-container>
Copier après la connexion
Copier après la connexion

浏览器输出结果是:

ngIf with a ng-template.
ngIf with an ng-container.
Copier après la connexion
Copier après la connexion

2.3 <span style="font-size: 16px;">ng-template</span><ng-container> 的配合使用

<ng-container *ngIf="showSearchBread; else tplSearchEmpty">
     暂时搜索不到您要的数据喔
</ng-container>
<ng-template #tplSearchEmpty>
     快快开始获取吧!
</ng-template>
Copier après la connexion

2.4 <span style="font-size: 16px;">ngTemplateOutlet</span>

插入 ng-template 创建的内嵌视图。 ngTemplateOutlet 是一个结构型指令,接收一个 TemplateRef 类型的值;

<div *ngTemplateOutlet="tpl1"></div>
<ng-template #tpl1>
  <span>I am span in template {{title}}</span>
</ng-template>
Copier après la connexion

*ngTemplateOutlet = "templateRefExp; content: contentExp "

  • templateRefExp: ng-template 元素的 #ID
  • contextExp:
    • 可空参数

    • content 是一个对象,这个对象可以包含一个 $implicitkey 作为默认值, 使用时在 模板 中用 let-key 语句进行绑定

    • content 的非默认字段需要使用 let-templateKey=contentKey 语句进行绑定

使用如下:

@Component({
  selector: &#39;ng-template-outlet-example&#39;,
  template: `
    <ng-container *ngTemplateOutlet="greet"></ng-container>
    <hr>
    <ng-container *ngTemplateOutlet="eng; context: myContext"></ng-container>
    <hr>
    <ng-container *ngTemplateOutlet="svk; context: myContext"></ng-container>
    <hr>
    <ng-template #greet><span>Hello</span></ng-template>
    <ng-template #eng let-name><span>Hello {{name}}!</span></ng-template>
    <ng-template #svk let-person="localSk"><span>Ahoj {{person}}!</span></ng-template>
`
})
class NgTemplateOutletExample {
  myContext = {$implicit: &#39;World&#39;, localSk: &#39;Svet&#39;};
}
Copier après la connexion

2.5 利用 <span style="font-size: 16px;">ngTemplateOutlet</span> 进行内容投影

@Component({
    selector: &#39;app-card&#39;,
    template: `
		<div class="card">
		  <div class="header">
		  	<ng-container *ngTemplateOutlet="headerTemplate; context: { $implicit: title, index: otherDate }"></ng-container>
		  </div>
		</div>
`
})
export class AppCardComponent {

	@ContentChild(&#39;header&#39;, { static: true }) headerTemplate: TemplateRef<any>;

	public title = &#39;Test&#39;;
	public otherDate = {
	 	auth: &#39;me&#39;,
	 	name: &#39;appCard&#39;
	};
}
Copier après la connexion

使用

<app-card>
  <ng-template #header let-label let-item="otherDate">
    <h1>Angular</h1> {{label}} (Test) and  {{otherDate | json}} ({auth: &#39;me&#39;, name: &#39;appCard&#39;})
  </ng-template>
</app-card>
Copier après la connexion

更多编程相关知识,请访问:编程教学!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:csdn.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal