Angular 的 @Input
以及 @Output
修飾器是用來讓父與子元件可以跨元件溝通資訊,應用範圍很廣,譬如說有些固定的表單功能我們可以把他切細,提供給各單元的表單套入使用,可以減少重複造輪子的問題,下面示範如何讓子元件改變父元件表單的內容。
父 ts
| import { Component, OnInit } from '@angular/core'; |
| import { FormBuilder } from '@angular/forms'; |
| |
| @Component({ |
| selector: 'app-example', |
| templateUrl: './example.component.html', |
| styleUrls: ['./example.component.scss'] |
| }) |
| export class ExampleComponent implements OnInit { |
| public form = this.fb.group({ |
| username: 'chan', |
| amount: 100 |
| }); |
| |
| constructor( |
| private fb: FormBuilder |
| ) { } |
| |
| ngOnInit(): void { |
| } |
| |
| public patchAmount(amount: number): void { |
| this.form.patchValue({ |
| amount: amount |
| }) |
| } |
| } |
父 html
| <h1>Input Output Example</h1> |
| <h3>{{ form.value | json }}</h3> |
| <form [formGroup]="form"> |
| <div> |
| <input type="text" formControlName="username"> |
| </div> |
| <div> |
| <app-example-number [amount]="form.get('amount')?.value" (patchParentAmount)="patchAmount($event)"></app-example-number> |
| </div> |
| </form> |
| |
子 ts
| import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; |
| |
| @Component({ |
| selector: 'app-example-number', |
| templateUrl: './example-number.component.html', |
| styleUrls: ['./example-number.component.scss'] |
| }) |
| export class ExampleNumberComponent implements OnInit { |
| @Input() amount: number = 0; |
| @Output() patchParentAmount = new EventEmitter<number>(); |
| |
| constructor() { } |
| |
| ngOnInit(): void { |
| } |
| |
| public updateAmount(): void { |
| this.patchParentAmount.emit(this.amount); |
| } |
| } |
子 html
<input type="number" [(ngModel)]="amount" (ngModelChange)="updateAmount()">
父元件傳了預設的 amount 過去給子元件,子元件透過監聽 ngModelChange
將改變的數字 emit 到父元件執行 patch form value 的動作,就可以做到互動更新了。