【问题标题】:failed to set the 'value' property on 'HTMLInputElement' in reactive form未能以反应形式在“HTMLInputElement”上设置“值”属性
【发布时间】:2019-02-07 18:40:41
【问题描述】:

以数据记录的形式,我上传了一张图片,图片会上传到服务器文件夹,名字会存入数据库。

在此编辑表单中,我从服务器获取文件名,我需要在此表单中填写 <input type="file">。使用 angular6 中的反应形式。

这是我在 ts 文件中的代码:

   ngOnInit() {
  this.EditForm=this.fb.group({
  imageName:['',Validators.compose([Validators.required])]
})
this.SetForm(this.dat)
}

  SetForm(dt:data){
   this.EditForm.setValue({imageName:[dt.imageName]});
  }

在 html 中:

<form [formGroup]="EditForm">
    <input type="file" #file formControlName="imageName">
</form>

这是我的代码:stackblitz

我不知道这个问题,我有 3 天有问题,请查看我的代码并更改它以解决此问题。

【问题讨论】:

  • 只是检查一下,你能上传文件吗?还是您只需要帮助在上传后“重命名”文件?

标签: javascript angular typescript angular6


【解决方案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.

作为现代浏览器的一种解决方法,DataTransfer 可用于更改文件输入值:

HTML(基于stackblitz):

<form [formGroup]="EditForm">
  <input id="my-input" type="file">
</form>

<button (click)="changeFileName()">Change File Name</button>

组件:

changeFileName() {
  const dataTransfer = new ClipboardEvent('').clipboardData || new DataTransfer();
  dataTransfer.items.add(new File(['my-file'], 'new-file-name'));
  const inputElement: HTMLInputElement = document.getElementById('my-input') as HTMLInputElement

  inputElement.files = dataTransfer.files;
}

【讨论】:

  • 是的,它显示了这个错误。但是我该如何解决这个错误?
  • 我已经根据您的代码创建了解决方法,使用 DataTransfer stackblitz.com/edit/… ,但它只适用于现代浏览器
【解决方案2】:

你可以用这个技巧重命名你的图像文件:

在您的 component.html 上,添加事件侦听器以侦听 change

<input type="file" (change)="onFileChange($event)" #file formControlName="imageName">

在您的 component.ts 上,这将使用更新的文件名创建一个新文件

onFileChange(event) {
  //console.log(event.target.files[0].name)
  var blob = event.target.files[0].slice(0, event.target.files[0].size, 'image/png'); 

  const newFile = new File([blob], this.dat.imageName, {type: 'image/png'})
  //console.log(newFile)
}

这会保留input 上的原始文件名,但您可以在post/put 请求中使用newFile 发送到后端。

【讨论】:

  • 我没有上传文件的问题。我设置编辑值的问题
  • 这将创建一个新文件,其名称与您在 stackblitz 中指定的名称相同。您可以对其进行 console.log ,它实际上会使用更新后的名称打印文件
【解决方案3】:

这对我有用;

changeFileName() {
  const inputElement: HTMLInputElement = document.getElementById('my-input') as HTMLInputElement
  inputElement.files = null;
}

【讨论】:

    【解决方案4】:

    删除 formControlName="image" 并将其替换为 (change)="onChangeImage()"

    【讨论】:

      【解决方案5】:

      对于那些使用 ReactJs 的用户,请从文件输入控件中删除 value 字段以解决问题。

      【讨论】:

      • 请同时添加代码 sn-p 并在答案中添加更简短的说明。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-26
      • 2018-11-17
      • 2018-10-02
      • 1970-01-01
      • 2017-06-03
      • 1970-01-01
      • 2020-04-03
      相关资源
      最近更新 更多