能否无需订阅Observable,从API为FormGroup/FormControl加载初始值?
不订阅Observable,用async管道为Angular表单控件加载初始值
当然可以做到,完全不用手动调用subscribe(),只通过async管道就能遵循ReactiveX规范完成表单初始值的加载,下面提供两种常用方案:
方案一:通过tap操作符在流中更新表单值
在组件中定义Observable流,利用tap操作符在流的副作用中更新FormControl的值,同时在模板中用async管道订阅该流(即使不需要显示流数据,也能触发流的执行):
import { FormControl } from '@angular/forms'; import { tap } from 'rxjs/operators'; // 定义表单控件 public name = new FormControl(''); // 定义API请求的Observable流,用tap更新表单值 public nameData$ = this.api.getName().pipe( tap(name => this.name.setValue(name)) ); constructor(private api: ApiService) {}
模板中只需添加一行触发流的代码(无需显示数据):
<ng-container>{{ nameData$ | async }}</ng-container>
方案二:直接从Observable流生成FormControl
更彻底的ReactiveX写法:直接从API流中生成FormControl实例,然后在模板中用async管道绑定到表单控件,全程无需手动创建或更新控件:
import { FormControl } from '@angular/forms'; import { map } from 'rxjs/operators'; // 直接从API流生成FormControl的Observable public nameControl$ = this.api.getName().pipe( map(name => new FormControl(name)) ); constructor(private api: ApiService) {}
模板中绑定控件:
<input [formControl]="nameControl$ | async">
如果是FormGroup,逻辑类似,只需把map里的内容换成创建FormGroup的逻辑:
public formGroup$ = this.api.getUserData().pipe( map(user => new FormGroup({ name: new FormControl(user.name), email: new FormControl(user.email) })) );
模板绑定:
<form [formGroup]="formGroup$ | async"> <input formControlName="name"> <input formControlName="email"> </form>
这两种方案都避免了手动订阅Observable,完全依赖async管道处理订阅与销毁,符合Angular的响应式表单和ReactiveX规范。
内容的提问来源于stack exchange,提问作者Lichay Tiram
相关产品推荐
相关产品推荐

