将图像从FileReader传递到Angular 6中的表单输入 [英] Pass image from FileReader to form input in Angular 6
问题描述
我尝试创建一个UI,其中有一个包含几个文本字段的表单,一个input type="file"
和div
,您可以拖放图像以与表单的其余部分一起上载.
I try to create an UI where there is a form with a couple of text fields, a input type="file"
and a div
that you can drop images to upload with the rest of the form.
我的目标/逻辑
使用相同的div
放下图像或单击它,然后像input type="file"
一样打开文件夹资源管理器.在实际上不可能拖放"的小屏幕上,启用单击是有意义的.并且由于表单中已经存在input type="file"
,因此没有理由从div
中获取图像并将其附加到表单等中.我尝试获取放置在div
中的图像,设置将其作为input type="file"
中的值,然后提交一次表单. (如果用户单击div
,则input type="file"
已经具有一个值,因此我可以再次自由提交表单.)
use the same div
to either drop an image or click on it and open the folder explorer like the input type="file"
behaves. Enabling clicking makes sense in small screens where it is practically impossible to "drag and drop". And since there is already a input type="file"
in the form there is no reason to take the image from the div
and append it to the form etc etc. I try to take the image that is dropped in the div
, set it as a value in the input type="file"
and submit the form once. (if user clicked on the div
, then the input type="file"
already has a value , so again I am free to submit the form again).
这是代码
<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
时,实际上是通过(click)='imageInput.click()'
So, when imageDrop
is clicked, actually call the imageChange
via (click)='imageInput.click()'
这是组件中的打字稿.
//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);
}
错误
当我尝试拖放图像时,我得到了指向该HTML行<div id="imageDrop" (click)='imageInput.click()' (drop)="drop($event)" (dragover)="allowDrop($event)" #imageDrop>
的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
,但是我确定它与
When I try to drag/drop an image, I get this 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
that points to this HTML line <div id="imageDrop" (click)='imageInput.click()' (drop)="drop($event)" (dragover)="allowDrop($event)" #imageDrop>
but I am sure it is related to the
if (this.imageUpload.controls.imageInput.value==null) {
this.imageUpload.controls.imageInput.reset(files[0] );
}
readfiles
功能的一部分.
有什么想法可以解决此问题,以便文件输入可以获取值,然后可以自由提交表单吗?
Any ideas how to fix this, so the file input can get a value and be then free to submit the form?
谢谢
推荐答案
好的,给你他错误的行是this.imageUpload.controls.imageInput.setValue(files[0]);
Okay, the line giving you he error was this.imageUpload.controls.imageInput.setValue(files[0]);
原因是,由于安全问题,浏览器将阻止您以编程方式设置文件.
The reason is, the browser will prevent you from programmatically setting the file that way due to security problems.
相反,您可以直接使用e.dataTransfer.files
:
Instead, you can use the e.dataTransfer.files
directly:
let input = this.imageUpload.controls.imageInput as any;
input.files = files;
Here is a fork of your stackblitz
这篇关于将图像从FileReader传递到Angular 6中的表单输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!