首页 > 解决方案 > 自定义 window.FileReader 方法在 Angular 区域外执行

问题描述

将 Ionic/Angular 项目从 Cordova 迁移到 Capacitor 后,我必须覆盖默认值window.FileReader才能以onload()以下方式执行该方法(https://github.com/ionic-team/capacitor/issues/1564):

constructor(
    appRef: ApplicationRef
  ) {
    class IonicFileReader extends window.FileReader {
      constructor() {
        super();

        // solution 3 - not working
        // this.onload = (e) => {
        //   this.onload(e);
        //   appRef.tick(); console.log('tick');
        // }

        // Solution 4 - working
        // setTimeout(() => {
        //   appRef.tick(); console.log('tick ctor');
        // }, 1000);

        // solution 5 - not working
        // super.onload = (e) => {
        //   this.onload(e);
        //   appRef.tick();
        //   console.log('tick');
        // };

        // solution 8 - not working
        // super.onload = (e) => {
        //   appRef.tick(); console.log('tick');
        //   super.onload.apply(this.onload);
        // };

        const zoneOriginalInstance = (this as any)[
          '__zone_symbol__originalInstance'
        ];
        return zoneOriginalInstance || this;
      }

      // solution 1 - not working
      // onload = (e) => {
      //   this.onload(e);
      //   appRef.tick(); console.log('tick');
      // }

      // solution 7 - not working
      // onload = function(e) {
      //   appRef.tick(); console.log('tick');
      //   return this.onload(e);
      // }

      // solution 9 = not working
      // refresh = function() {
      //   appRef.tick();
      // }
      // (window.FileReader as any).refresh();
    }


    // solution 6 - not working
    // window.FileReader.prototype = new IonicFileReader();
    // window.FileReader.prototype.onload = function(ev) {
    //   this.onload(ev);
    //   appRef.tick(); console.log('tick prototype');
    // }

    // solution 2 - not working
    // window.FileReader.prototype = IonicFileReader.prototype;

    window.FileReader = IonicFileReader;
  }

我在里面重写了它constructorAppModule以便通过ApplicationRef为了调用更改检测机制。不幸的是,没有解决方案(除了不可接受的解决方案 4 之外)有效。

在此函数调用期间应启动更改检测:

function blobToText(blob: any): Observable<string> {
    return new Observable<string>((observer: any) => {
        if (!blob) {
            observer.next("");
            observer.complete();
        } else {
            let reader = new FileReader();
            reader.onload = event => {
                observer.next((<any>event.target).result);
                observer.complete();
              
                // CHANGE DETECTION SHOULD BE FIRED HERE

                // solution 9, 9.1 - not working
                // (reader as any).refresh();
                // (reader as any).refresh;
            };
            reader.readAsText(blob);
        }
    });
}

标签: javascriptangulartypescriptionic4capacitor

解决方案


推荐阅读