我有一个函数,可以在其中创建一个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);
然后我的回调无法正常工作。例如,handleFileSelect
在NewComponent
类中。该类还具有以下变量
@ViewChild("thumbnailContainer",{read:ViewContainerRef})
thumbnailContainerRef:ViewContainerRef;
handleFileSelect
使用thumbnailContainerRef
。如果没有bind(this
),则thumbnailContainerRef
是undefined
,但是有了bind(this)
时,thumbnailContainerRef
就会被定义
我为什么需要做
reader.onload = this.handleReaderLoaded.bind(this);
reader.onerror = this.handleFileLoadError.bind(this);
不能只是做
reader.onload = this.handleReaderLoaded;
reader.onerror = this.handleFileLoadError;
我认为,由于方法是在组件类内部定义的,因此this
将始终映射到组件类。