上一節中咱們定義了一個響應式表單,其中表單數據是在定義的時候就初始化好的,可是不少時候數據須要異步獲取,好比打開一個編輯頁面,須要:css
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
import { delay } from 'rxjs/operators';
// /api/users/1
export interface User {
id: number;
firstName: string;
lastName: string;
about: string;
}
const fakeData = {
id: 0,
firstName: 'Cory',
lastName: 'Rylan',
about: 'Web Developer'
};
@Injectable()
export class UserService {
constructor() { }
loadUser() {
return of<User>(fakeData).pipe(
delay(2000)
);
}
}
複製代碼
組件中,調用該方法html
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { UserService, User } from './user.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
form: FormGroup;
user$: Observable<User>;
constructor(
private formBuilder: FormBuilder,
private userService: UserService) { }
ngOnInit() {
this.form = this.formBuilder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
about: []
});
this.user$ = this.userService.loadUser().pipe(
// tap 返回的仍是 Observable 這裏咱們不訂閱,咱們在模板中使用 async pipe 和 if else 語句實現有條件的顯示錶單
tap(user => this.form.patchValue(user))
);
// .subscribe();
}
submit() {
if (this.form.valid) {
console.log(this.form.value);
}
}
}
複製代碼
修改模板api
<form *ngIf="user$ | async; else loading" [formGroup]="form" (ngSubmit)="submit()">
<label for="firstname">First Name</label>
<input id="firstname" formControlName="firstName" />
<div *ngIf="form.controls.firstName.errors?.required && form.controls.firstName.touched" class="error">
*Required
</div>
<label for="lastname">Last Name</label>
<input id="lastname" formControlName="lastName" />
<div *ngIf="form.controls.lastName.errors?.required && form.controls.lastName.touched" class="error">
*Required
</div>
<label for="about">About</label>
<textarea id="about" formControlName="about"></textarea>
<button [disabled]="!form.valid">Save Profile</button>
</form>
<ng-template #loading>
Loading User...
</ng-template>
複製代碼
你會發現頁面打開後一開始顯示Loading User...
過了大概2s後文字消失並顯示錶單。bash