将图像从FileReader传递到Angular 6中的表单输入

时间:2018-09-15 17:39:55

标签: angular file-upload angular6 image-uploading angular-reactive-forms

我尝试创建一个UI,在该UI中有一个包含几个文本字段的表单,一个input type="file"和一个div,您可以拖放图像以与表单的其余部分一起上传。

我的目标/逻辑

使用相同的div拖放图像或单击图像,然后像input type="file"一样打开文件夹资源管理器。在实际上不可能“拖放”的小屏幕上,启用单击是有意义的。并且由于表单中已经存在input type="file",因此没有理由从div中获取图像并将其附加到表单等中。我尝试获取放在{中的图像{1}},将其设置为div中的值,然后提交一次表单。 (如果用户单击input type="file",则div已经有一个值,因此我可以再次提交表单。)

这是代码

input type="file"

因此,当单击 <div id="imageDrop" (click)='imageInput.click()' (drop)="drop($event)" (dragover)="allowDrop($event)" #imageDrop> </div> <input type="file" formControlName="imageInput" required #imageInput id="imageInput" (change)='imageChange($event)' > <!-- use css to hide it --> 时,实际上是通过imageDrop调用imageChange

这是组件中的打字稿。

(click)='imageInput.click()'

错误

当我尝试拖放图像时,我得到指向该HTML行//imageUpload is the name of the reactive form acceptedImageTypes = {'image/png': true,'image/jpeg': true,'image/gif': true}; @ViewChild('imageDrop') imageDrop; allowDrop(e) { e.preventDefault(); } drop(e) { e.preventDefault(); //clear in case we selected something before via click this.imageUpload.controls.imageInput.reset(); this.imageDrop.innerHTML=""; this.checkfiles(e.dataTransfer.files); } imageChange(event){ this.imageDrop.innerHTML=""; this.checkfiles(event.target.files); }//imageChange checkfiles(files){ if (this.acceptedImageTypes[files[0].type] !== true){ this.imageDrop.nativeElement.innerHTML="Not an image"; return; } else if (files.length>1){ this.imageDrop.nativeElement.innerHTML="Only one image/time"; return; } else { this.readfiles(files); } }//checkfiles readfiles(files){ const reader = new FileReader(); let image = new Image(); reader.onload = (event) =>{ this.imageDrop.nativeElement.innerHTML=""; let fileReader = event.target as FileReader; image.src = fileReader.result; image.width = 150; this.imageDrop.nativeElement.appendChild(image); }; reader.readAsDataURL(files[0]); if (this.imageUpload.controls.imageInput.value==null) { //if its null then means that we dragging an img, so the previous image from the input file is deleted //now we got to put this image to the input file in order to submit the form this.imageUpload.controls.imageInput.reset(files[0] ); } }//readfiles imageUploadSubmitted(){ //when form submit, for now just check image value to check if its the right one console.log('IMAGE VALUE SUBMIT = = ',this.imageUpload.controls.imageInput.value); } 的{​​{1}},但我确信它与

相关
ERROR DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string

<div id="imageDrop" (click)='imageInput.click()' (drop)="drop($event)" (dragover)="allowDrop($event)" #imageDrop>函数的一部分。

有什么想法可以解决此问题,以便文件输入可以获取值,然后可以自由提交表单吗?

谢谢

2 个答案:

答案 0 :(得分:8)

好的,给你他错误的那一行是this.imageUpload.controls.imageInput.setValue(files[0]);

原因是,由于安全问题,浏览器将阻止您以编程方式设置文件。

相反,您可以直接使用e.dataTransfer.files

let input = this.imageUpload.controls.imageInput as any;
input.files = files;  

Here is a fork of your stackblitz

答案 1 :(得分:1)

您要尝试执行的操作无法通过这种方式实现(由于每个人所说的原因,安全原因等)。

要实现所需的功能,Angular解决方案是通过实现 ControlValueAccessor 创建一个使用[[ngModel)] formControlName的自定义组件。

通过这样做,您将可以将所需的任何内容作为值放入FormControl。

实现ControlValueAccessor是许多教程的一部分:https://blog.angularindepth.com/never-again-be-confused-when-implementing-controlvalueaccessor-in-angular-forms-93b9eee9ee83

在这里您可以找到我自己的一些代码,一个在Form中工作的图像选择器:

https://github.com/xrobert35/asi-ngtools/blob/master/src/components/asi-image-chooser/asi-image-chooser.component.ts

示例:https://ng-tools.asi.fr/views/showroom/asi-ngtools/components/asi-image-chooser