【发布时间】:2020-01-01 14:40:09
【问题描述】:
我正在努力理解如何合并两个可观察对象并利用它们的合并产品。我看过无数关于 mergeMap、switchMap、flatMap、大理石图等的视频,但我仍然不明白合并 observables 是如何工作的。我觉得在使用 RxJS 时我不会高效,甚至不会正确。
我有一个正在订阅的 observable,我还想订阅我的代码中特定表单数组的 valueChanges observable。但是,我需要确保仅在正确构建表单数组之后才进行第二次订阅,否则我会收到 null 错误。
显然,这样做是在我第一次订阅的下一个函数中订阅 valueChanges,但这是一种不好的做法,我想避免它。但是,我不确定应该以何种方式构建我的代码,以便在不使用嵌套订阅的情况下获得我想要的行为。
setSettings$(serial: string) {
return this.getSettingsFromSerial$(serial).pipe(
tap(val => {
this.settingsState.savedSettingsState = val;
this.settingsState.ipRestrictionEnabled = val.ipRestrictionSettings.ipRestrictionEnabled;
if(val.ipRestrictionSettings.ipRanges.length === 0){
this.addEmptyRange();
}
else
{
for (const i of val.ipRestrictionSettings.ipRanges) {
this.addRange(i.startRange, i.endRange, i.label);
}
}
this.settingsState.displaySettings = true;
this.settingsState.displayForm = true;
this.hideRangeErrorsUntilNotPristine(); <-- I need to merge (?) this with my first observable to ensure that it happens after the form is built.
})
);
}
// TODO :: Cancel this on destroy
hideRangeErrorsUntilNotPristine(){
this.ipRangeFormArray.valueChanges.subscribe( res => {
let formGroups = this.ipRangeFormArray.controls;
for(let i = 0; i < formGroups.length; i++){
if(formGroups[i].pristine === true) {
this.settingsState.ipRangeValidStates[i].displayError = false;
}
else {
this.settingsState.ipRangeValidStates[i].displayError = true;
}
}
});
}
【问题讨论】:
-
您的 formarray 是从服务器获取 json 数据并需要创建它,还是您只是从您项目中存在的 json 配置数据生成 formarray?
-
表单数组正在使用来自服务器的 json 数据生成
-
如果你想等待一个 observable 发出值来触发第二个 observable,你可以使用
concatMap。它确保在第一个发出值之后调用第二个。你可以看看这个interactive marble diagrams有一个更好的理解。 -
因为这是一个建议。我不确定表单是否总是被创建,当他尝试订阅 valueChanges 时,因为这会导致未定义。通常我会使用 afterViewInit() 回调。
-
@sagat 不幸的是,在这种情况下 afterViewInit() 将不起作用,因为异步调用发生在对 afterViewInit 的调用之后