我有一个现有函数,该函数完成调用HTTP终结点的大量工作,该工作负责管理Angular组件中的某些逻辑。出现了一个需求,以便在某些情况下,我们需要调用所有现有逻辑,但是还需要进行另一个HTTP调用。下面是我的尝试的带注释的版本。
public resolveComponent(action: string) {
//if called with no parameters, don't do anything
//otherwise, call one of the two endpoints.
let preAction = (x: any) => {
if (action === "replay") {
return this.remediationService
.replayRemediation(this.workflow.Id);
}
else if (action === "remove") {
return this.remediationService
.removeRemediation(this.workflow.Id);
}
else {
return of([]);
}
}
this.remediationService
.resolveComponent(component)
.pipe(
//the line below was what I added after new requirement
mergeMap(preAction),
mergeMap(x => {
//grabs updated data from server
return this.remediationService.remediationComponent(component.Id);
})
)
.subscribe((x: SomeModel) => {
//logic happens
});
}
这可以按预期执行工作,但这是有条件链接可观察对象的最好方法吗?
答案 0 :(得分:4)
您可以添加自己的pipeIf
:
import { from, Observable, of, NEVER } from 'rxjs';
import { mergeMap, map, filter } from 'rxjs/operators';
from([10, 11, 12, 13])
.pipe(
map(x => x + 10),
pipeIf(x => x > 21,
filter(x => x > 22),
map(x => x + 100)
),
)
.subscribe(console.log);
function pipeIf(predicate, ...pipes) {
return function (source) {
return source.pipe(
mergeMap(value => predicate(value) ? of(value).pipe(...pipes) : of(value))
)
}
}
// 20
// 21
// 123
答案 1 :(得分:4)
使用iif
rxjs。
iif
接受一个条件函数和两个Observable。什么时候
*订阅了操作员返回的Observable,将调用条件函数。
答案 2 :(得分:2)
iif
可以有条件地写入 observable:
iif(() => cond, obs1, obs2)
= cond ? obs1 : obs2
iif(() => cond, obs1)
= cond ? obs1 : EMPTY
但是 iif
不适用于运营商。如果要在 .pipe()
中有条件地编写运算符,请使用:
cond ? delay(1000) : interval(500)
对于空运算符,使用 identity
:
import { identity } from 'rxjs'
cond ? delay(1000) : identity
其中 identity
实际上是 x => x
答案 3 :(得分:0)
这个对我有用,
in html template
<formio [form]="formDescription" (submit)="submit.emit($event)" "" [submission]="submission"></formio>
in typescript
export class FormioViewComponent implements OnInit {
@Input() formDescription;
@Input() submission:any;
@Output() submit :EventEmitter<any> = new EventEmitter();
constructor() { }
ngOnInit() {
}
}
答案 4 :(得分:0)
您可能只使用merge()
(如果需要流是连续的,则使用concat()
而不是两个mergeMap()
,因为您似乎不需要新的输出流作为现有流的输入:
const replayObservable = of("Has been Replayed");
const removeObservable = of("Has been Removed");
const existingObservable = of(
"Finally, do what you already did before the CR."
);
const resolveComponent = (action?: string) => {
const newSource = of();
const targetWithoutNull = newSource.pipe(
merge(
iif(
() => !!action,
iif(() => action == "replay", replayObservable, removeObservable)
),
existingObservable
)
);
targetWithoutNull.subscribe(x => console.log(x));
};
resolveComponent("replay");
resolveComponent("remove");
resolveComponent();
请注意,第一个iif()
仅具有2个参数。如果条件指向一个未定义的参数,iif()
将完成流,因此在这种情况下,将仅预订existingObservable。