2021/08/11

Input And Output In Angular

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 的動作,就可以做到互動更新了。

沒有留言: