首页 > 代码库 > [Angular] @ContentChild and ngAfterContentInit

[Angular] @ContentChild and ngAfterContentInit

@ContentChild normally works with ngAfterContentInit lifecycle.

@ContentChild is used for looking into child component‘s props.

 

For example, we a app component:

      <auth-form         (submitted)="loginUser($event)">        <h3>Login</h3>        <auth-remember          (checked)="rememberUser($event)">        </auth-remember>        <button type="submit">          Login        </button>      </auth-form>

Inside it define a ‘auth-form‘ component, and for auth-form component it has ‘h3‘, ‘auth-remember‘ and ‘button‘ component as children.

 

Auth-form:

    <div>      <form (ngSubmit)="onSubmit(form.value)" #form="ngForm">        <ng-content select="h3"></ng-content>        <label>          Email address          <input type="email" name="email" ngModel>        </label>        <label>          Password          <input type="password" name="password" ngModel>        </label>        <ng-content select="auth-remember"></ng-content>        <ng-content select="button"></ng-content>      </form>    </div>

Inside auth-form, it use <ng-content> (content projection) to show ‘h3, button & auth-remember‘ component. So what we want to do here is "inside auth-form component, listen to auth-remember‘s checked event, using its value to toggle a message div".

 

Add a message div:

    <div>      <form (ngSubmit)="onSubmit(form.value)" #form="ngForm">        <ng-content select="h3"></ng-content>        <label>          Email address          <input type="email" name="email" ngModel>        </label>        <label>          Password          <input type="password" name="password" ngModel>        </label>        <ng-content select="auth-remember"></ng-content>        <div *ngIf="showMessage">You account will be kept for 30 days</div>        <ng-content select="button"></ng-content>      </form>    </div>

 

Using @ContentChild to get the component object.

import { Component, Output, EventEmitter, AfterContentInit, ContentChild } from ‘@angular/core‘;import { User } from ‘./auth-form.interface‘;import {AuthRememberComponent} from ‘./auth-remember.component‘;@Component({  selector: ‘auth-form‘,  template: `      ...  `})export class AuthFormComponent implements AfterContentInit{  showMessage: boolean;  @ContentChild(AuthRememberComponent) remember: AuthRememberComponent;  @Output() submitted: EventEmitter<User> = new EventEmitter<User>();  onSubmit(value: User) {    this.submitted.emit(value);  }  ngAfterContentInit(): void {    if(this.remember) {      this.remember.checked.subscribe((checked: boolean) => {        this.showMessage = checked;      })    }  }}

 

If we check ‘this.remember‘:

技术分享

We can subscribe ‘this.remember.checked‘ to get whether ‘auth-remember‘ is checeked or not, and assign the value to ‘showMessage‘ var.

 

@ContentChild is really powerful, it can get any props on the child component.

For exmaple, we can add an @Input value and a private prop on to the auth-remember component.

import { Component, Output, EventEmitter, Input } from ‘@angular/core‘;@Component({  selector: ‘auth-remember‘,  template: `    <label>      <input type="checkbox" (change)="onChecked($event.target.checked)">      Keep me logged in    </label>  `})export class AuthRememberComponent {  @Output() checked: EventEmitter<boolean> = new EventEmitter<boolean>();  @Input() role: string;  myName: string = "Auth-remember";  onChecked(value: boolean) {    this.checked.emit(value);  }}

And from the console log, we can see, we get everthing about the auth-remember component.

技术分享

[Angular] @ContentChild and ngAfterContentInit