【发布时间】:2020-11-30 12:38:32
【问题描述】:
问题
所以。我正在尝试使用 异步数据 预填充一个反应式表单,这将发生很大变化。 asyncData$ 从 AppComponent 馈送到处理表单的子组件 - FormComponent 中的 @input()。
Subscribing 在 dataForm$ 的 tap() 运算符中是 ONLY 我可以做到的valueChanges 工作并实际发出值,但嵌套订阅是不行的,所以我想找到一个更好/更清洁的解决方案来避免这种情况 - 最好是使用 observables。可能只是我遗漏了一些明显的东西
有人有建议吗?
表单本身必须是可观察的
应用组件
<div>
<app-form [asyncData]="asyncData$ | async"></app-form>
</div>
export class AppComponent implements OnInit {
title = 'observableForm';
asyncData$: ReplaySubject<Data> = new ReplaySubject<Data>(1);
ngOnInit(): void {
setTimeout(() => this.asyncData$.next( {
id: 42,
name: 'Han Solo',
heShotFirst: true
} as Data), 2000);
}
}
表单组件
<div *ngIf="(dataForm$ | async) as dataForm">
<form [formGroup]="dataForm" style="padding: 5rem; display: grid; place-items: center;">
<div>
<label>
Id
<input type="text" [formControlName]="'id'">
</label>
<label>
Name
<input type="text" [formControlName]="'name'">
</label>
<br>
<label>
He shot first
<input type="radio" [value]="true" [formControlName]="'heShotFirst'">
</label>
<label>
He did not
<input type="radio" [value]="false" [formControlName]="'heShotFirst'">
</label>
</div>
</form>
<div *ngIf="(lies$ | async) === false" style="display: grid; place-items: center;">
<h1>I Must Not Tell Lies</h1>
</div>
</div>
export class FormComponent implements OnInit, OnDestroy {
@Input() set asyncData(data: Data) { this._asyncData$.next(data); }
_asyncData$: ReplaySubject<Data> = new ReplaySubject<Data>(1);
dataForm$: Observable<FormGroup>;
valueChangesSub$: Subscription;
lies$: Subject<boolean> = new Subject<boolean>();
constructor(private fb: FormBuilder) { }
ngOnInit(): void {
this.dataForm$ = this._asyncData$.pipe(
map(data => {
return this.fb.group({
id: [data?.id],
name: [data?.name],
heShotFirst: [data?.heShotFirst]
});
}),
tap(form => {
if (this.valueChangesSub$ != null) {
this.valueChangesSub$.unsubscribe();
}
return form.valueChanges.subscribe(changes => {
console.log(changes)
this.lies$.next(changes.heShotFirst);
});
})
);
}
ngOnDestroy(): void {
this.valueChangesSub$.unsubscribe();
}
}
【问题讨论】:
-
是否可以用 Stackblitz 构建一个小的工作示例来说明它是如何不工作的?
-
我很好奇为什么表单本身需要是可观察的?
标签: angular typescript rxjs reactive-programming angular-reactive-forms