Detailed explanation of angular content projection

Detailed explanation of angular content projection

Single content projection

Using ng-content to implement

<!-- Component- app-content-single -->
<div>
  <h2>Title</h2>
  <!-- Projection content display position-->
  <ng-content></ng-content>
</div>
<!-- Usage -->
<app-content-single>
  <div>this is content</div>
</app-content-single>

Multi-content projection

Using ng-content to implement

<!-- Component- app-content-more -->
<div>
  <h3>Herder Title</h3>
  <ng-content select=".header"></ng-content>
  <h3>Body Title</h3>
  <ng-content select="[body]"></ng-content>
  <h3>Default Title</h3>
  <ng-content></ng-content>
  <h3>Footer Title</h3>
  <ng-content select="footer"></ng-content>
</div>
<!-- Usage -->
<app-content-more>
  <div>this is default01</div>
  <div class="header">this is header</div>
  <div>this is default02</div>
  <div body>this is body</div>
  <div>this is default03</div>
  <footer>this is footer</footer>
  <div>this is default04</div>
</app-content-more>

Conditional content projection - ng-template , ng-container , directive , etc. to achieve

Content projection for a single condition

For example: suppose there is a list of people now. When the money of a person is greater than 200, the content defined in the template in the component is added

Define an appChildRef directive to cooperate with ng-template to obtain the template

import { Directive, TemplateRef } from '@angular/core';
@Directive({
  selector: '[appChildRef]'
})
export class ChildRefDirective {
  constructor(public templateRef: TemplateRef<any>) { }
}

app-persons-html

<div class="list-item" *ngFor="let person of persons;">
  <div>Name: {{ person.name }}</div>
  <div>Money: {{ person.money }}</div>
  <div *ngIf="person.money > 200">
    <ng-container *ngIf="childRef" [ngTemplateOutlet]="childRef.templateRef"></ng-container>
  </div>
</div>

app-persons - ts

import { Component, ContentChild, OnInit } from '@angular/core';
import { ChildRefDirective } from '../../../../directives/child-ref.directive';
@Component({
  selector: 'app-persons',
  templateUrl: './persons.component.html',
  styleUrls: ['./persons.component.scss']
})
export class PersonsComponent implements OnInit {
  persons: { name: string; money: number; }[] = [
    { name: 'Jack', money: 120 },
    { name: 'Li Li', money: 210 },
    { name: 'Zhang San', money: 170 },
  ];
  @ContentChild(ChildRefDirective, { static: true }) childRef!: ChildRefDirective;
  constructor() { }
  ngOnInit(): void { }
}

use

<app-persons>
  <ng-template appChildRef>
    <div style="font-size: 14px; color: red;">this is child ref content</div>
  </ng-template>
</app-persons>

Rendering

Rendering

Multiple conditional content projection

Eg: Now we want to bind the embedded template to display through the fields in the persons data

appChildRef Adjustment

import { Directive, Input, TemplateRef } from '@angular/core';
@Directive({
  selector: '[appChildRef]'
})
export class ChildRefDirective {
  // Accept the defined template name - display the corresponding template content through this name and the render field in persons @Input() appChildRef!: string;
  constructor(public templateRef: TemplateRef<any>) { }
}

app-persons-html

<div class="list-item" *ngFor="let person of persons;let i=index;">
  <div>Name: {{ person.name }}</div>
  <div>Money: {{ person.money }}</div>
  <!-- <div *ngIf="person.money > 200">
    <ng-container *ngIf="childRef" [ngTemplateOutlet]="childRef.templateRef"></ng-container>
  </div> -->
  <div *ngIf="person.render && tempRefs[person.render]">
    <!-- Use the ngTemplateOutlet directive to pass the current person data to the template -->
    <ng-container *ngTemplateOutlet="tempRefs[person.render].templateRef; context: { $implicit: person, i: i }"></ng-container>
  </div>
</div>

app-persons - ts

import { Component, ContentChild, ContentChildren, OnInit, QueryList } from '@angular/core';
import { ChildRefDirective } from '../../../../directives/child-ref.directive';
@Component({
  selector: 'app-form-unit',
  templateUrl: './form-unit.component.html',
  styleUrls: ['./form-unit.component.scss']
})
export class FormUnitComponent implements OnInit {
  persons: { name: string; money: number; render?: string; }[] = [
    { name: 'Jack', money: 120, render: 'temp1' },
    { name: '李莉', money: 210, render: 'temp2' },
    { name: '张三', money: 170, render: 'temp3' },
  ];
  // @ContentChild(ChildRefDirective, { static: true }) childRef!: ChildRefDirective;
  @ContentChildren(ChildRefDirective) childrenRef!: QueryList<ChildRefDirective>;
  get tempRefs() {
    const aObj: any = {};
    this.childrenRef.forEach(template => {
      const key: string = template.appChildRef;
      aObj[key] = template;
    })
    return aObj;
  }
  constructor() { }
  ngOnInit(): void { }
}

use

<app-persons>
  <ng-template appChildRef="temp1" let-person let-index="i">
    <div style="font-size: 14px; color: red;">{{index}}-{{person.name}}: this is temp1</div>
  </ng-template>
  <ng-template appChildRef="temp2" let-person let-index="i">
    <div style="font-size: 14px; color: green;">{{index}}-{{person.name}}: this is temp2</div>
  </ng-template>
  <ng-template appChildRef="temp3" let-person let-index="i">
    <div style="font-size: 14px; color: orange;">{{index}}-{{person.name}}: this is temp3</div>
  </ng-template>
</app-persons>

Rendering

Rendering

Summarize

This article ends here. I hope it can be helpful to you. I also hope you can pay more attention to more content on 123WORDPRESS.COM!

You may also be interested in:
  • Detailed explanation of Angular component projection
  • Detailed explanation of the implementation of shared modules in Angular projects
  • Detailed explanation of Angular routing sub-routes
  • Detailed explanation of Angular routing basics
  • Detailed explanation of the life cycle of Angular components (Part 2)
  • Detailed explanation of Angular component life cycle (I)
  • Detailed explanation of the middleman mode of Angular components

<<:  How to reduce the root directory of XFS partition format in Linux

>>:  SQL Aggregation, Grouping, and Sorting

Recommend

How to create a Docker repository using Nexus

The warehouse created using the official Docker R...

How to configure SSL for koa2 service

I. Introduction 1: SSL Certificate My domain name...

Detailed installation tutorial of mysql 5.7 under CentOS 6 and 7

You always need data for development. As a server...

Detailed explanation of the usage of position attribute in HTML (four types)

The four property values ​​of position are: 1.rel...

Examples of using the ES6 spread operator

Table of contents What are spread and rest operat...

Markup Languages ​​- What to learn after learning HTML?

Click here to return to the 123WORDPRESS.COM HTML ...

Detailed explanation of the use of state in React's three major attributes

Table of contents Class Component Functional Comp...

Notes on upgrading to mysql-connector-java8.0.27

Recently, an online security scan found a vulnera...

How to adjust the log level of nginx in Docker

Table of contents Intro Nginx Dockerfile New conf...

CentOS 6 Compile and install ZLMediaKit analysis

Install ZLMediaKit on centos6 The author of ZLMed...

js realizes a gradually increasing digital animation

Table of contents background Achieve a similar ef...

Introduction to HTML method of opening link files using hyperlinks

a and href attributes HTML uses <a> to repr...

Basic principles of MySQL scalable design

Table of contents Preface 1. What is scalability?...

HTML Tutorial: Collection of commonly used HTML tags (6)

These introduced HTML tags do not necessarily ful...