響應(yīng)式表單
FormControl
的 valueChanges
屬性和 statusChanges
屬性包含了會發(fā)出變更事件的可觀察對象。
例子
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl, AbstractControl } from '@angular/forms';
import { concat, merge, zip, combineLatest, race } from 'rxjs/index';
import { filter, map, startWith, } from 'rxjs/internal/operators';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
form: FormGroup;
constructor(
private formBuilder: FormBuilder,
) { }
ngOnInit() {
this.form = this.formBuilder.group({
username: ['', Validators.required],
hobby: [''],
});
// 監(jiān)聽整個表單
this.form.valueChanges
.subscribe( res => console.log(res));
}
}
HTML
<form [formGroup]="form">
username: <input type="text" name="username" formControlName="username">
hobby:
<select name="hobby">
<option value="sleep">sleep</option>
<option value="play">play</option>
</select>
</form>
完善驗證,只有通過驗證才輸出內(nèi)容 filter 是rxjs提供的運算符
this.form.valueChanges
.pipe(
filter(() => this.form.valid)
)
.subscribe(res => console.log(res));
如果需要額外的邏輯,只需要在pipe添加相應(yīng)的運算符谤专。比如這里在結(jié)果里追加上次更新時間,字段名為lastTime
this.form.valueChanges
.pipe(
filter(() => this.form.valid),
map(data => {
data.lastTime = new Date();
return data
})
)
.subscribe(res => console.log(res));
另一種寫法怠噪,監(jiān)聽各個元素
// 如果要監(jiān)聽單個表單元素
const username$ = this.form.get('username').pipe(startWith(this.form.get('username').value))
const hobby$ = this.form.get('hobby').pipe(startWith(this.form.get('hobby').value))
// combineLatest,它會取得各個 observable 最后送出的值杜跷,再輸出成一個值
// 這個有個問題是只有合并的元素都產(chǎn)生值才會輸出內(nèi)容傍念,所以在上面使用startWith賦初始化值
combineLatest(username$, status$)
.pipe(
map(([username, status]) => ({username, status}))
)
.subscribe(res => console.log(res));
結(jié)合返回Observable的組件 Angular Material
Angular Material 是基于Angular的前端框架,國外使用度高葛闷。
他提供的組件有些方法返回的是Observable憋槐,比如Dialog的afterAllClosed,SnackBar的afterOpened, afterDismissed
比如某需要孵运,提示消失1s后跳轉(zhuǎn)頁面
優(yōu)化前的代碼:
this.snackbar.success(response);
setTimeout(function () {
this.router.navigate([`/login`]);
}, 1000);
優(yōu)化后的代碼:
import { delay } from 'rxjs/operators';
...
this.snack.success(response).afterDismissed()
.pipe(delay(1000))
.subscribe(() => {
this.router.navigate([`/login`]);
});