我正在使用另一个Observable
的输入过滤Observable
- 过滤的输入来自用户。
使用RxJS运算符combineLatest
完成过滤。使用这意味着在订阅此流时,在两个源Observable都发出之前不会发出任何值 - 在创建任何用户输入之前,我希望创建的流在创建时发出(不进行任何过滤)。 / p>
我认为我应该使用startWith
运算符,因此流在创建时有一个发射,但我无法弄清楚如何从Observable中播种。使用Observable是因为数据来自Firebase,并由FirebaseListObservable
处理。
下面是我目前正在做的拼凑版本。
let tagInput = document.getElementById('tags');
let tagExclusionStream = Observable
.fromEvent(tagInput, 'input')
.map((e: any) => createsArrayFromInput(e.target.value));
let allTags: Observable<any[]> = getAllTags();
let filteredTags = allTags
.combineLatest(tagExclusionStream, (tags, tagExclusions) => {
return tags.filter((tag: any) => tagExclusions.indexOf(tag.$key) == -1)
});
// I want this to print out without needing the tagExclusionStream to emit first
filteredTags.subscribe(tags => console.log("Tags:", tags))
请告诉我,如果我的方法完全关闭/我有一个更好的方法,因为我是RxJS的新手。
答案 0 :(得分:8)
startWith
仅使用concat
internally。
const startValue$ = of('start with this')
concat(startValue$, source$)
或编写您自己的运算符
function startFrom<T, O extends ObservableInput<any>>(start: O): OperatorFunction<T, T | ObservedValueOf<O>> {
return (source: Observable<T>) => concat(start, source)
}
source$.pipe(
startFrom(startValue$)
)
确保startValue$
完成
source$
完成后,新的Observable将切换到startValue$
。
所以如果Observable开始是一个长期存在的Observable,例如ReplaySubject
,您只需要关心最近的值即可确保输入的Observable完整,例如与take(1)
。
const { ReplaySubject, concat, of } = rxjs;
const { take } = rxjs.operators;
const source$ = of('source-1', 'source-2')
const replay = new ReplaySubject(1)
replay.next('subject-1')
replay.next('subject-2')
const startWith$ = replay.pipe(take(1)) // <-- take one item and complete
const o$ = concat(startWith$, source$)
o$.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.5/rxjs.umd.min.js" integrity="sha256-85uCh8dPb35sH3WK435rtYUKALbcvEQFC65eg+raeuc=" crossorigin="anonymous"></script>
答案 1 :(得分:3)
我认为这会解决问题:
let filteredTags = allTags
.combineLatest(tagExclusionStream.startWith(''), (tags, tagExclusions) => {
return tags.filter((tag: any) => tagExclusions.indexOf(tag.$key) == -1)
});
或者,如果您在不同的地方使用tagExclusionStream
,则可以执行此操作:
let tagExclusionStream = Observable
.fromEvent(tagInput, 'input')
.map((e: any) => createsArrayFromInput(e.target.value))
.startWith('');