耀极客论坛

 找回密码
 立即注册
查看: 613|回复: 0

angular内容投影详解

[复制链接]

193

主题

-17

回帖

276

积分

中级会员

Rank: 3Rank: 3

积分
276
发表于 2022-5-8 02:08:07 | 显示全部楼层 |阅读模式
  这篇文章主要为大家介绍了angular内容投影,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助


单内容投影
  利用ng-content来实现
  1. ‹!-- 组件 - app-content-single -->
  2. ‹div>
  3.   ‹h2>标题‹/h2>
  4.   ‹!-- 投影内容显示位置 -->
  5.   ‹ng-content>‹/ng-content>
  6. ‹/div>
  7. ‹!-- 使用 -->
  8. ‹app-content-single>
  9.   ‹div>this is content‹/div>
  10. ‹/app-content-single>
复制代码
多内容投影
  利用ng-content来实现
  1. ‹!-- 组件 - app-content-more -->
  2. ‹div>
  3.   ‹h3>Herder Title‹/h3>
  4.   ‹ng-content select=".header">‹/ng-content>
  5.   ‹h3>Body Title‹/h3>
  6.   ‹ng-content select="[body]">‹/ng-content>
  7.   ‹h3>Default Title‹/h3>
  8.   ‹ng-content>‹/ng-content>
  9.   ‹h3>Footer Title‹/h3>
  10.   ‹ng-content select="footer">‹/ng-content>
  11. ‹/div>
  12. ‹!-- 使用 -->
  13. ‹app-content-more>
  14.   ‹div>this is default01‹/div>
  15.   ‹div class="header">this is header‹/div>
  16.   ‹div>this is default02‹/div>
  17.   ‹div body>this is body‹/div>
  18.   ‹div>this is default03‹/div>
  19.   ‹footer>this is footer‹/footer>
  20.   ‹div>this is default04‹/div>
  21. ‹/app-content-more>
复制代码
  有条件的内容投影-ng-template, ng-container, directive 等来配合实现

单个条件的内容投影
  eg: 假设现在有一个人员列表,当某个人的money大于200的时候,额外添加组件中模板定义的内容
  定义一个 appChildRef 指令来配合 ng-template 获取模板
  1. import { Directive, TemplateRef } from '@angular/core';
  2. @Directive({
  3.   selector: '[appChildRef]'
  4. })
  5. export class ChildRefDirective {
  6.   constructor(public templateRef: TemplateRef‹any>) { }
  7. }
复制代码

app-persons - html
  1. ‹div class="list-item" *ngFor="let person of persons;">
  2.   ‹div>Name: {{ person.name }}‹/div>
  3.   ‹div>Money: {{ person.money }}‹/div>
  4.   ‹div *ngIf="person.money > 200">
  5.     ‹ng-container *ngIf="childRef" [ngTemplateOutlet]="childRef.templateRef">‹/ng-container>
  6.   ‹/div>
  7. ‹/div>
复制代码

app-persons - ts
  1. import { Component, ContentChild, OnInit } from '@angular/core';
  2. import { ChildRefDirective } from '../../../../directives/child-ref.directive';
  3. @Component({
  4.   selector: 'app-persons',
  5.   templateUrl: './persons.component.html',
  6.   styleUrls: ['./persons.component.scss']
  7. })
  8. export class PersonsComponent implements OnInit {
  9.   persons: { name: string; money: number; }[] = [
  10.     { name: '杰克', money: 120 },
  11.     { name: '李莉', money: 210 },
  12.     { name: '张三', money: 170 },
  13.   ];
  14.   @ContentChild(ChildRefDirective, { static: true }) childRef!: ChildRefDirective;
  15.   constructor() { }
  16.   ngOnInit(): void { }
  17. }
复制代码

使用
  1. ‹app-persons>
  2.   ‹ng-template appChildRef>
  3.     ‹div>this is child ref content‹/div>
  4.   ‹/ng-template>
  5. ‹/app-persons>
复制代码

效果图


多个条件内容投影
  eg: 现在希望通过 persons 数据中的字段进行绑定内嵌的模板来显示

appChildRef 调整
  1. import { Directive, Input, TemplateRef } from '@angular/core';
  2. @Directive({
  3.   selector: '[appChildRef]'
  4. })
  5. export class ChildRefDirective {
  6.   // 接受定义模板名称-通过这个名称和 persons 中的render字段对应进行显示对应的模板内容
  7.   @Input() appChildRef!: string;
  8.   constructor(public templateRef: TemplateRef‹any>) { }
  9. }
复制代码
app-persons - html
  1. ‹div class="list-item" *ngFor="let person of persons;let i=index;">
  2.   ‹div>Name: {{ person.name }}‹/div>
  3.   ‹div>Money: {{ person.money }}‹/div>
  4.   ‹!-- ‹div *ngIf="person.money > 200">
  5.     ‹ng-container *ngIf="childRef" [ngTemplateOutlet]="childRef.templateRef">‹/ng-container>
  6.   ‹/div> -->
  7.   ‹div *ngIf="person.render && tempRefs[person.render]">
  8.     ‹!-- 配合 ngTemplateOutlet 指令给template传递当前person的数据 -->
  9.     ‹ng-container *ngTemplateOutlet="tempRefs[person.render].templateRef; context: { $implicit: person, i: i }">‹/ng-container>
  10.   ‹/div>
  11. ‹/div>
复制代码
app-persons - ts
  1. import { Component, ContentChild, ContentChildren, OnInit, QueryList } from '@angular/core';
  2. import { ChildRefDirective } from '../../../../directives/child-ref.directive';
  3. @Component({
  4.   selector: 'app-form-unit',
  5.   templateUrl: './form-unit.component.html',
  6.   styleUrls: ['./form-unit.component.scss']
  7. })
  8. export class FormUnitComponent implements OnInit {
  9.   persons: { name: string; money: number; render?: string; }[] = [
  10.     { name: '杰克', money: 120, render: 'temp1' },
  11.     { name: '李莉', money: 210, render: 'temp2' },
  12.     { name: '张三', money: 170, render: 'temp3' },
  13.   ];
  14.   // @ContentChild(ChildRefDirective, { static: true }) childRef!: ChildRefDirective;
  15.   @ContentChildren(ChildRefDirective) childrenRef!: QueryList‹ChildRefDirective>;
  16.   get tempRefs() {
  17.     const aObj: any = {};
  18.     this.childrenRef.forEach(template => {
  19.       const key: string = template.appChildRef;
  20.       aObj[key] = template;
  21.     })
  22.     return aObj;
  23.   }
  24.   constructor() { }
  25.   ngOnInit(): void { }
  26. }
复制代码
使用
  1. ‹app-persons>
  2.   ‹ng-template appChildRef="temp1" let-person let-index="i">
  3.     ‹div>{{index}}-{{person.name}}: this is temp1‹/div>
  4.   ‹/ng-template>
  5.   ‹ng-template appChildRef="temp2" let-person let-index="i">
  6.     ‹div>{{index}}-{{person.name}}: this is temp2‹/div>
  7.   ‹/ng-template>
  8.   ‹ng-template appChildRef="temp3" let-person let-index="i">
  9.     ‹div>{{index}}-{{person.name}}: this is temp3‹/div>
  10.   ‹/ng-template>
  11. ‹/app-persons>
复制代码
效果图


总结

  本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|耀极客论坛 ( 粤ICP备2022052845号-2 )|网站地图

GMT+8, 2023-3-24 15:01 , Processed in 0.076870 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表