@ContentChild && ngAfterContentInit

Posted by Tim Lin on 2019-01-24

承接上一篇 ng-content 的用法
現在我們希望在勾選 checkbox 時會顯示訊息,
也就是取得 child content 的 checkbox 值, 塞到 showMessage, 來顯示這段文字

1
2
3
<!--當 showMessage 為 true 時顯示 You will be logged in for 30 days-->
<div *ngIf="showMessage">
You will be logged in for 30 days </div>

用 @ContentChild 取得 child content

但在 auth-form.componet.ts 要如何取得 auth-rember.componet.ts (child content) checkbox 的值呢?

使用

1
2
3
4
<!--auth-form.componet.ts -->
...
@ContentChild(AuthRememberComponent) remember: AuthRememberComponent;
...

這樣就能取得 dom, auth-rember.componet.ts (child content) 的內容

1
<ng-content select="auth-remember"></ng-content>

實作 ngAfterContentInit()

接著 implements lifecycle-hooks AfterContentInit 實做 ngAfterContentInit()
auth-rember.componet.ts (child content) 的 checked 值
帶回來塞入我們自訂的 showMessage 裡面, 如此就大功告成!

1
2
3
4
5
6
7
8
9
10
11
12
13
export class AuthFormComponent implements AfterContentInit {

showMessage: boolean;

@ContentChild(AuthRememberComponent) remember: AuthRememberComponent;

@Output() submitted: EventEmitter<User> = new EventEmitter<User>();

ngAfterContentInit() {
if (this.remember) {
this.remember.checked.subscribe((checked: boolean) => this.showMessage = checked);
}
}

auth-form.componet.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import { Component, Output, EventEmitter, ContentChild, AfterContentInit } from '@angular/core';

import { AuthRememberComponent } from './auth-remember.component';

import { User } from './auth-form.interface';

@Component({
selector: 'auth-form',
template: `
<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 will be logged in for 30 days
</div>
<ng-content select="button"></ng-content>
</form>
</div>
`
})
export class AuthFormComponent implements AfterContentInit {

showMessage: boolean;

@ContentChild(AuthRememberComponent) remember: AuthRememberComponent;

@Output() submitted: EventEmitter<User> = new EventEmitter<User>();

ngAfterContentInit() {
if (this.remember) {
this.remember.checked.subscribe((checked: boolean) => this.showMessage = checked);
}
}

onSubmit(value: User) {
this.submitted.emit(value);
}

}

Result

Reference