将图像从 FileReader 传递到 Angular 6 中的表单输入 [英] Pass image from FileReader to form input in Angular 6

查看:29
本文介绍了将图像从 FileReader 传递到 Angular 6 中的表单输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试创建一个 UI,其中有一个带有几个文本字段的表单、一个 input type="file" 和一个 div 可以放置图像与表格的其余部分一起上传.

我的目标/逻辑

使用相同的 div 来放置图像或单击它并像 input type="file" 那样打开文件夹资源管理器.在几乎不可能拖放"的小屏幕中启用点击是有意义的.并且由于表单中已经存在 input type="file" ,因此没有理由从 div 中获取图像并将其附加到表单等中.我尝试获取 div 中放置的图像,将其设置为 input type="file" 中的值并提交一次表单.(如果用户点击了 div ,那么 input type="file" 已经有一个值,所以我可以再次提交表单).

这是代码

 <div id="imageDrop" (click)='imageInput.click()' (drop)="drop($event)" (dragover)="allowDrop($event)" #imageDrop>

<input type="file" formControlName="imageInput" required #imageInput id="imageInput" (change)='imageChange($event)' ><!-- 使用css隐藏它-->

因此,当点击 imageDrop 时,实际上是通过 (click)='imageInput.click()'

调用 imageChange>

这是组件中的打字稿.

//imageUpload 是反应形式的名称AcceptedImageTypes = {'image/png': true,'image/jpeg': true,'image/gif': true};@ViewChild('imageDrop') imageDrop;允许下降(e){e.preventDefault();}下降(e){e.preventDefault();//清除以防我们之前通过单击选择了某些内容this.imageUpload.controls.imageInput.reset();this.imageDrop.innerHTML="";this.checkfiles(e.dataTransfer.files);}图像变化(事件){this.imageDrop.innerHTML="";this.checkfiles(event.target.files);}//图像变化检查文件(文件){if (this.acceptedImageTypes[files[0].type] !== true){this.imageDrop.nativeElement.innerHTML="不是图像";返回;}else if (files.length>1){this.imageDrop.nativeElement.innerHTML="只有一张图片/时间";返回;}else { this.readfiles(files);}}//检查文件读取文件(文件){const reader = new FileReader();让图像=新图像();reader.onload = (事件) =>{this.imageDrop.nativeElement.innerHTML="";让 fileReader = event.target 作为 FileReader;image.src = fileReader.result;图像宽度 = 150;this.imageDrop.nativeElement.appendChild(image);};reader.readAsDataURL(files[0]);如果(this.imageUpload.controls.imageInput.value==null){//如果它为null则意味着我们拖动了一个img,因此输入文件中的前一个图像被删除//现在我们必须将此图像放入输入文件以提交表单this.imageUpload.controls.imageInput.reset(files[0]);}}//读取文件imageUploadSubmitted(){//当表单提交时,现在只需检查图像值以检查它是否正确console.log('IMAGE VALUE SUBMIT == ',this.imageUpload.controls.imageInput.value);}

错误

当我尝试拖放图像时,出现此 ERROR DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be set to the program指向此 HTML 行的空字符串 <div id="imageDrop" (click)='imageInput.click()' (drop)="drop($event)" (dragover)="allowDrop($event)" #imageDrop> 但我确定它与

if (this.imageUpload.controls.imageInput.value==null) {this.imageUpload.controls.imageInput.reset(files[0]);}

readfiles 函数的一部分.

任何想法如何解决这个问题,以便文件输入可以获得一个值,然后可以自由地提交表单?

谢谢

解决方案

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

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

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

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

这是你的 stackblitz 的一个分支

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.

My goal / logic

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).

Here is the code

  <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 -->

So, when imageDrop is clicked, actually call the imageChange via (click)='imageInput.click()'

This is the typescript in the component.

//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);
  }

Errors

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] );            
} 

part of the readfiles function.

Any ideas how to fix this, so the file input can get a value and be then free to submit the form?

Thanks

解决方案

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.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆