This article will take you through the content projection in Angular components. Content projection is very similar to the slot in Vue. It is very useful when encapsulating components. Let’s experience it together
[Related tutorial recommendations: "angular tutorial 》】
The container component is written like this
<div> 编号1 <ng-content></ng-content> </div>
Business components are used like this
<app-page-container> 未指定投影位置的内容会被投影到无select属性的区域 </app-page-container>
Container components are used like this Write
Use tag to lock the projection position
Use class to lock the projection position
Lock the projection position with a custom component name
Lock the projection position with a custom attribute
<div> 编号2 <ng-content select="h3"></ng-content> <ng-content select=".my-class"></ng-content> <ng-content select="app-my-hello"></ng-content> <ng-content select="[content]"></ng-content> </div>
Business components are used like this
<app-page-container> <h3>使用标签锁定投影位置</h3> <div class="my-class">使用class锁定投影位置</div> <app-my-hello>使用自定义组件名称锁定投影位置</app-my-hello> <div content>使用自定义属性锁定投影位置</div> </app-page-container>
Demo
Useng-container
to wrap child elements and reduce unnecessary dom layers, similar to the template in vue
The container component is written like this
<div> 编号4 <ng-content select="question"></ng-content> </div>
Business components are written like this
<app-page-container> <ng-container ngProjectAs="question"> <p>内容投影酷吗?</p> <p>内容投影酷吗?</p> <p>内容投影酷吗?</p> <p>内容投影酷吗?</p> </ng-container> </app-page-container>
Chinese website description:
- If your component needs to_
conditionally_render content or render content multiple times, you should configure the component to Accepts an ng-template element containing content to be conditionally rendered.
- In this case, it is not recommended to use the ng-content element because as long as the user of the component provides the content, even if the component never defines the ng-content element or the ng- The content element is located inside the
- Using the ng-template element, you can have the component explicitly render content based on any conditions you want, and render it multiple times. Angular does not initialize the content of an ng-template element until the element is explicitly rendered.
Use ng-containerDefine our projection block
ngTemplateOutlet directive to render
ng-template elements.
*ngIf to control whether to render the projection.
<div> 编号3 <ng-content select="[button]"></ng-content> <p *ngIf="expanded"> <ng-container [ngTemplateOutlet]="content.templateRef"> </ng-container> </p> </div>
In the business component we use ng-template to wrap our actual elements.
my-hello component only does log output in ngOnInit() to observe the printing situation.<app-page-container> <div button> <button appToggle>切换</button> </div> <ng-template appContent> <app-my-hello>有条件的内容投影~</app-my-hello> </ng-template> </app-page-container>Copy after login
Now you will find that the page does not render normally as smoothly as before, because our logic has not been colluded yet, let's continue. Create a command and register it in NgModule. You must register before you can use it~
The command needs to be registered~import { Directive, TemplateRef } from '@angular/core'; @Directive({ selector: '[appContent]', }) export class ContentDirective { constructor(public templateRef: TemplateRef<unknown>) {} }Copy after login
We will define it again A command to control the display/hiding of the logo in the component
The command needs to be registered~@Directive({ selector: '[appToggle]', }) export class ToggleDirective { @HostListener('click') toggle() { this.app.expanded = !this.app.expanded; } constructor(public app: PageContainerComponent) {} }Copy after login
State the definition just now in our container component Content instructions, the page currently does not report an error~
export class PageContainerComponent implements OnInit { expanded: boolean = false; @ContentChild(ContentDirective) content!: ContentDirective; }
You can see from the log that when we switch the expanded logo of the container component, there is only the open state
The my-hello component will be initialized. Although the following
ngIf cannot see the rendered content on the page, the component has actually been initialized.
<div *ngIf="false"> <ng-content *ngIf="false" select="app-my-hello"></ng-content> </div>
Use these two decorators to project the components Perform the operation
Use annotations to define the projected component in the business component
@ContentChild(HelloWorldComp) helloComp: HelloWorldComp; @ContentChildren(HelloWorldComp) helloComps: QueryList<HelloWorldComp>;
Execute in thengAfterContentInit()hook Then operate the projected component
Use annotations to define sub-components in business components
ngAfterViewInit()After the hook is executed, operate the direct sub-component For more programming-related knowledge, please visit: Introduction to Programming! ! The above is the detailed content of A brief analysis of content projection in Angular component learning. For more information, please follow other related articles on the PHP Chinese website!@ViewChild(HelloWorldComp)
helloComp: HelloWorldComp;
@ViewChildren(HelloWorldComp)
helloComps QueryList<HelloWorldComp>;
We have just written here about the use of components. Our writing skills are limited, so come on. Got~