没有bind(this)回调函数不起作用

时间:2019-01-27 07:20:38

标签: javascript typescript angular6 filereader

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

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),则thumbnailContainerRefundefined,但是有了bind(this)时,thumbnailContainerRef就会被定义

我为什么需要做

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

不能只是做

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

我认为,由于方法是在组件类内部定义的,因此this将始终映射到组件类。

0 个答案:

没有答案