首页 > 解决方案 > 每次更改输入后如何不创建流?

问题描述

我有以下代码:

public upload(): void {
    const fileinput = document.getElementById('file');
    fileinput.click();
    fileinput.addEventListener('change', this.handleFileInput.bind(this));
}

private handleFileInput(event) {
    try {
        const input = event.target as HTMLInputElement;
        const reader = new FileReader();
        const { objectId } = this.object;
        const file = input.files[0];

        reader.onload = () => {
            event.target.value = null;
            this.objectDetailsService
                .upload(file, objectId)
                .subscribe(
                    () => //,
                    () => //,
                );
        };
        reader.readAsArrayBuffer(file);
    } catch (e) {
        console.log(e);
    }
}

我有时应该允许加载相同的文件。当用户选择另一个此代码创建为新流。如何避免?

标签: javascriptangular

解决方案


你问如何申请是对的switchMap。一种方法是创建一个 observable 来处理异步回调onload。然后您可以应用运算符,例如switchMap调用其他异步函数。

另外我建议直接在模板中附加事件处理程序,而不是document.getElementById('file');在控制器中使用。

尝试以下

* .ts

import { Observable, Observer, timer } from 'rxjs';
import { switchMap } from 'rxjs/operators';

public handleFileInput(event) {
  const input = event.target as HTMLInputElement;
  const file = input.files[0];
  this.readFile(file).pipe(
    switchMap((file: any) => {
      const { objectId } = this.object;
      return this.objectDetailsService.upload(file, objectId);
    })
  ).subscribe({
    next: () => console.log('File uploaded'),
    error: (error: any) => console.log('Error:', error),
  });
}

readFile(file): Observable<any> {
  const reader = new FileReader();
  reader.readAsArrayBuffer(file);

  return new Observable((observer: Observer<any>) => {
    reader.onload = (ev: ProgressEvent) => {
      observer.next(file);
      observer.complete();
    };
    reader.onerror = (error: any) => {
      observer.error(error);
    };
  });
}

* .html

Select file: <input type="file" (change)="handleFileInput($event)" />

工作示例:Stackblitz


推荐阅读