[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.

时间: 2024-10-05 23:26:47

[Angular] @ContentChild and ngAfterContentInit的相关文章

[Angular] Difference between ngAfterViewInit and ngAfterContentInit

Content is what is passed as children. View is the template of the current component. The view is initialized before the content and ngAfterViewInit() is therefore called before ngAfterContentInit(). @Component({ selector: 'parent-cmp', template: '<d

[Angular] Write Compound Components with Angular’s ContentChild

Allow the user to control the view of the toggle component. Break the toggle component up into multiple composable components that can be rearranged by the app developer. Compound component mainly for rendering flexibility. It hides the implements de

Angular 2 ElementRef

Angular 2 的口号是 - "一套框架,多种平台.同时适用手机与桌面(One framework.Mobile & desktop.)",即 Angular 2 是支持开发跨平台的应用,比如:Web应用.移动Web应用.原生移动应用和原生桌面应用等. 为了能够支持跨平台,Angular 2 通过抽象层封装了不同平台的差异,统一了 API 接口.如定义了抽象类 Renderer .抽象类 RootRenderer 等.此外还定义了以下引用类型:ElementRef.Temp

[Angular] @ViewChildren and QueryLists (ngAfterViewInit)

When you use @ViewChildren, the value can only be accessable inside ngAfterViewInit lifecycle. This is somehow different from @ViewChild, which value can be accessed from ngAfterContentInit lifecycle. import { Component, ChangeDetectorRef, Output, Vi

[Angular] Using ngTemplateOutlet to create dynamic template

I can use <tamplete> syntax and a entry component as a container to create a dynamic component. Notice it will create a empty div as a placeholder in the DOM. If we don't wanner this empty div, we can actually using ng-conainer together with ngTempl

Angular 2.0 从0到1 (七)

第一节:Angular 2.0 从0到1 (一)第二节:Angular 2.0 从0到1 (二)第三节:Angular 2.0 从0到1 (三)第四节:Angular 2.0 从0到1 (四)第五节:Angular 2.0 从0到1 (五)第六节:Angular 2.0 从0到1 (六)第七节:Angular 2.0 从0到1 (七)第八节:Angular 2.0 从0到1 (八)番外:Angular 2.0 从0到1 Rx-隐藏在Angular 2.x中利剑番外:Angular 2.0 从0到

[Angular 2] Generate Angular 2 Components Programmatically with entryComponents &amp; ViewContainerRef

You can generate Angular 2 components using a combination of ViewContainer and ComponentFactory, but you must always remember to add the components you want to generate to your list of entryComponents otherwise the compiler will optimize the componen

[Angular 2] Create template with Params

Angular 2 templates have a special let syntax that allows you to define and pass a context when they’re being generated. import {Component, ViewChild, ViewContainerRef, ComponentFactoryResolver, ViewChild} from '@angular/core'; import {SimpleService}

[Angular 2] Generate and Render Angular 2 Template Elements in a Component

Angular 2 Components have templates, but you can also create templates inside of your templates using Angular 2 ViewContainer’s createEmbeddedView for more visual control of how you want to generate elements inside of your Angular 2 templates. import