首页 > 解决方案 > 没有绑定(this),回调不起作用

问题描述

我有一个函数,我在其中创建一个FileReader回调函数并将其分配给load处理error程序

handleFileSelect(files:ArrayLike<File>):FileReader|null{
    console.log("got file upload event: ");
    console.log(" image attachment count: ",this.currentImageAttachmentCount);
    if(this.currentImageAttachmentCount >= this.maxImageAttachmentCount)
    {
      console.log("reached max attachment size");
      this.showDialog("You can't attach more files",new DialogContext("",""));
      return null;
    }
    console.log("files selected:",files);
    console.log("total selected: ",files.length);
    for(let i=0;i<files.length;i++)
    {
      console.log("files name:",files[i].name);
      console.log("files object:",files[i])
    }

    //working with only 1 file at the moment
    let file = files[0];
    console.log("file at index 0 ",file);
    if (files && file) {
      console.log("reading file");
      /*
      The FileReader object lets web applications ASYNCHRONOUSLY read the contents of files (or raw data buffers) stored on the user's computer,
      using File or Blob objects to specify the file or data to read.
       */
      let reader:FileReader = new FileReader();

      /*load/onload will be called when the read operation successfully completes.

       */

      //TODOM - Why if I don't bind this then in unit testing, the 'this' of handleReaderLoaded seem to be different fromm the component!!
      reader.onload = this.handleReaderLoaded.bind(this);
      reader.onerror = this.handleFileLoadError.bind(this);
      reader.onloadend = this.debugPrintFileEvents;//TODOM - remove these or make them more useful
      reader.onloadstart = this.debugPrintFileEvents;
      reader.onprogress = this.debugPrintFileEvents;
      reader.onabort = this.debugPrintFileEvents;

      //The readAsBinaryString method is used to start reading the contents of the specified Blob or File.
      reader.readAsDataURL(file);
      this.currentImageAttachmentCount++;
      return reader;
    } else{
      return null;
    }

  }

我正在调用newPracticeQuestionComponent.handleFileSelect以下单元测试,而该单元测试将依次调用handleReaderLoaded.

fit('should call error handler when file doesn\'t get loaded successfully', () => {
    let newComponent = component;
    console.log("component is ",newPracticeQuestionComponent);

    let file1 = new File(["dd"], "file1",{type:'image/png',
    endings:'transparent'});


    let reader = newComponent.handleFileSelect([file1]);
    expect(reader).toBeTruthy();
    expect(reader.onerror.name).toEqual(newComponent.handleFileLoadError.name);

  });

我注意到如果我不bind(this)使用

  reader.onload = this.handleReaderLoaded.bind(this);
  reader.onerror = this.handleFileLoadError.bind(this);

那么我的回调无法正常工作。例如,handleFileSelectNewComponent课堂上。该类还具有以下变量

@ViewChild("thumbnailContainer",{read:ViewContainerRef})
  thumbnailContainerRef:ViewContainerRef;

handleFileSelect使用thumbnailContainerRef. 没有bind(this), thumbnailContainerRefisundefined 但有bind(this),thumbnailContainerRef被定义

为什么我需要做

reader.onload = this.handleReaderLoaded.bind(this);
      reader.onerror = this.handleFileLoadError.bind(this);

不能只是做

reader.onload = this.handleReaderLoaded;
      reader.onerror = this.handleFileLoadError;

我认为由于方法是在组件类内部定义的,所以this总是会映射到组件类。

标签: javascripttypescriptangular6filereader

解决方案


推荐阅读