Это было настоящее путешествие ... Но я надеюсь, что этот ответ даст некоторым пользователям новое понимание.
Вот несколько решений, с которыми я работал изначально, с последним перечисленным решением, которое я в итоге реализовал.
Исходное решение:
const obs = new Observable<{ item: FileItem, response: string }>(sub => {
this.uploader.onCompleteItem = (item: FileItem, response: string) => sub.next({ item, response });
return () => this.uploader.onCompleteItem = undefined;
});
bindCallback((x: (item: FileItem, response: string) => any) => this.uploader.onCompleteItem = x)()
.pipe(
takeUntil(this.onDestroySubj),
tap(([item, response]) => {
const data = JSON.parse(response);
this.imageArray.push(...data );
this.uploader.removeFromQueue(item);
})
).subscribe();
Единственная проблема с решением, приведенным выше, заключается в том, что bindCallBack
срабатывает только один раз.
Более изысканное решение:
Observable.create((sub: Subscriber<[FileItem, string]>) => {
this.uploader.onCompleteItem = (item: FileItem, response: string) => sub.next([item, response]);
return () => this.uploader.onCompleteItem = undefined;
}).pipe(
takeUntil(this.onDestroySubj),
tap(([item, response]) => {
const data = JSON.parse(response);
this.imageArray.push(...data );
this.uploader.removeFromQueue(item);
})
).subscribe();
Это заставило меня задуматься .. И я подумал об использовании fromEvent
, потому что он подписывается на jQuery действия и события браузера, но только если не написана оболочка. Именно это привело меня к моему окончательному решению, используя fromEventPattern
:
Окончательное решение: (полный код)
ngOnInit() {
fromEventPattern<Parameters<FileUploader['onCompleteItem']>>(x => this.uploader.onCompleteItem = x).pipe(
takeUntil(this.onDestroySubj),
tap(([item, response]) => {
this.imageArray = this.imagesSubject.getValue();
const data = JSON.parse(response);
this.imageArray.push(...data );
this.uploader.removeFromQueue(item);
// because I'm using a Subject
this.imagesSubject.next(this.imageArray);
})
).subscribe();
}
ngOnDestroy() {
this.onDestroySubj.next();
}