Home > Web Front-end > JS Tutorial > A brief discussion on how Angular uses ng-content for content projection

A brief discussion on how Angular uses ng-content for content projection

青灯夜游
Release: 2021-07-02 11:00:59
forward
2539 people have browsed it

A brief discussion on how Angular uses ng-content for content projection

In this article, we will explore how to use ng-content for content projection to create flexible and reusable components. The

ng-content

ng-content element is a placeholder for inserting external or dynamic content. The parent component passes external content to the child component, and when Angular parses the template, the external content is inserted in the child component template where ng-content appears.

We can use content projection to create reusable components. These components have similar logic and layout and can be used in many places. Generally we often use it when encapsulating some public components. [Related tutorial recommendations: "angular tutorial"]

Do not use content projection

In order to understand why ng-content should be used for content projection, First let's create a very common button component.

btn.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-btn',
  templateUrl: './btn.component.html',
  styleUrls: ['./btn.component.scss'],
})
export class BtnComponent {
  constructor() {}

  onClick($event: any) {
    console.log($event);
  }
}
Copy after login

btn.component.html

<button (click)=onClick($event)>
  Click Me
</button>
Copy after login

In this component, the text of the button is always Click Me, if Do we want to pass different text in? You may think of the most commonly used @Input decorator, but what if we don’t just want to pass in text, but a piece of html? At this time, you need to use the protagonist of this article: ng-content.

Single Slot Content Projection

The most basic form of content projection is Single Slot Content Projection. Single slot content projection means creating a component into which we can project a component.

To create a component that uses single-slot content projection, we just need to make some simple modifications to the component above: replace Click Me with <ng-content> </ng-content>.

btn.component.html

<button (click)=onClick($event)>
  <ng-content></ng-content>
</button>
Copy after login

Where the btn component is used:

<app-btn>Cancel</app-btn>
<app-btn><b>Submit</b></app-btn>
Copy after login

In<app-btn></app-btn># The content in ## will be passed to the btn component and displayed in ng-contnet.

Multi-slot content projection

The btn component above is very simple, but in fact

ng-content is more powerful than this. A component can have multiple slots, and each slot can specify a CSS selector that determines what content goes into that slot. This mode is called Multi-Slot Content Projection. Using this mode, we must specify where we want the projected content to appear. This can be accomplished by using the select attribute of ng-content.

To create a component that uses multi-slot content projection, you need to do the following:

  • Create a component.

  • In the component template, add the

    ng-content element where you want the projected content to appear.

  • Add the

    select attribute to the ng-content element. The selectors used by Angular support any combination of tag names, attributes, CSS classes, and :not pseudo-classes.

Let’s create a more complex card component.

card.component.html

<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>
</div>
Copy after login

Where the card component is used:

app.component.html

<app-card>
  <header>
    <h1>Angular</h1>
  </header>
  <content>One framework. Mobile & desktop.</content>
  <footer><b>Super-powered by Google </b></footer>
</app-card>

<app-card>
  <header>
    <h1 style="color:red;">React</h1>
  </header>
  <content>A JavaScript library for building user interfaces</content>
  <footer><b>Facebook Open Source </b></footer>
</app-card>
Copy after login

If in

app- Is there content in card that does not belong to header, content, and footer? For example, if you use the app-card component as follows:

app.component.html

<app-card>
  <header>
    <h1>Angular</h1>
  </header>
  <div>Not match any selector</div>
  <content>One framework. Mobile & desktop.</content>
  <footer><b>Super-powered by Google </b></footer>
  <div>This text will not not be shown</div>
</app-card>
Copy after login

, you will find that both

div are not rendered in page, in order to solve this problem, we can add a ng-content tag without any selector in the component. All content that does not match any other slot will be rendered in this one.

card.component.html

<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>
Copy after login

ngProjectAs

In some cases, we need to use

ng-container to wrap some content and pass it to in the component. Most of the time it's because we need to use structural directives like ngIf or ngSwitch etc. For example, headers are passed to the card component only under certain circumstances.

In the example below, we wrap the header in

ng-container.

<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>
Copy after login

Due to the existence of

ng-container, the header part is not rendered to the slot we want to render, but is rendered to ng- which does not provide any selector. content in.

In this case, we can use the

ngProjectAs attribute.

Add this attribute to the above

ng-container, and you can render it according to our expectations.

<app-card>
  <ng-container ngProjectAs=&#39;header&#39;>
    ...
</app-card>
Copy after login
For more programming-related knowledge, please visit:

Programming Teaching! !

The above is the detailed content of A brief discussion on how Angular uses ng-content for content projection. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:juejin.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template