【问题标题】:Error in Angular 8 reactive form file uploadAngular 8 反应式表单文件上传错误
【发布时间】:2022-02-10 20:13:35
【问题描述】:

我正在尝试在 Angular 8 中上传文件,但出现以下错误并且无法弄清楚

ERROR DOMException: "An attempt was made to use an object that is not, or is no longer, usable"

当我选择一个文件时出现上述错误。以下是我的方法

组件.ts

import { Component, OnInit } from '@angular/core';
import {FormArray,FormBuilder,FormGroup,FormControl, Validators, NgForm} from "@angular/forms";
import { ApiService } from '../apis/commonapis';

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
  userForm : FormGroup;
  constructor(private fb : FormBuilder,private service : ApiService) { }

  ngOnInit() {
    this.newForm(); 
  }
  newForm = function(){
    this.userForm = this.fb.group({
      email : ['',Validators.compose([Validators.required])],
      photo : ['',Validators.compose([Validators.required])]
    })
  }
  PostData(form: NgForm) {
    //console.log(form);
    var formData = new FormData();
    formData.append('photo', this.userForm.get('photo').value);
    console.log(formData);
    /*this.service.PostApi("http://localhost:1900/addUser",formData).subscribe(res=>{
                console.log(res);
                location.reload();
            });
     */
  }

  onFileSelect(event) { // here is some error
    if (event.target.files.length > 0) {
      const file = event.target.files[0];
      this.userForm.get('photo').setValue(file);
    }
  }
}

模板文件

<form [formGroup]="userForm" (ngSubmit)="PostData(userForm)" enctype="multipart/form-data"> 
        <div class="form-group row">
                <label for="email" class="col-sm-2 col-form-label">Email</label>
                <div class="col-sm-9">
                        <input type="text"  formControlName='email' class="form-control" required>
                </div>                                                                                                    
        </div>

        <div class="form-group row">
                <label for="photo" class="col-sm-2 col-form-label">Photo</label>
                <div class="col-sm-9">
                        <input type="file"  formControlName='photo' class="form-control" required  (change)="onFileSelect($event)">
                </div>                                                                                                    
        </div>

        <div class="form-group row">

                <div class="col-sm-10">
                        <input type="submit"  value='submit' class="form-control">
                </div>                                                                                                    
        </div>

</form>

我已经搜索过上面的错误,它说这个错误是在没有加载 DOM 时出现的,但是这里的元素已经加载了,而不是为什么这个错误?

【问题讨论】:

标签: angular


【解决方案1】:

这个错误很奇怪。 当我测试您的代码时,我收到以下错误:

错误:无法在“HTMLInputElement”上设置“value”属性:此输入元素接受文件名,该文件名只能以编程方式设置为空字符串。

只需删除 HTML 模板中的 formControlName='photo' 即可。

编辑

为了显示错误,您必须使用与常规输入不同的方法。文件输入没有 ng-touched、ng-untouched 或 ng-dirty 类,因此您不能执行以下操作:

<p *ngIf="photo.invalid && (photo.dirty || photo.touched)"> Show an error </p>

我想您想在用户点击提交按钮时显示文件输入的错误。 如果是这样,您可以执行以下操作:

// add a property to your class
isPhotoError = false;

PostData(form: NgForm) {
    if (this.userForm.get('photo').invalid) {
      this.isPhotoError = true;
    }
    //do something
 }

photoErrorHandler() {
    if (this.userForm.get('photo').hasError('required')) {
      return 'Photo required';
    }
  }
<p *ngIf="isPhotoError"> {{ photoErrorHandler() }} </p>

考虑将您的 onFileSelect(event) 替换为:

onFileSelect(event: Event) {
    const file = (event.target as HTMLInputElement).files[0];
    this.userForm.patchValue({ photo: file });
    this.userForm.get('photo').updateValueAndValidity();
  }

patchValue -> 允许你定位单个控件;

updateValueAndValidity() -> 通知 Angular 该值已更改,它必须检查该值是否有效。

我创建了这个StackBlitz 来检查代码(对样式感到抱歉)。如果您在项目中需要图片预览,我已经包含了图片预览。

【讨论】:

  • 感谢您的回答,但如果我删除 formControlName='photo'。比我如何显示与此字段相关的错误。
【解决方案2】:

我遇到了类似的问题。就像评论中提到的Passionate Code 一样,解决方案是从&lt;input&gt; 中删除formControlName。在我看来,问题出在以下事实,我们正在使用空字符串初始化 FormControl,然后我们尝试输入 File 类型对象,可能是某些内部类型验证引发了正在发生的异常。在我看来,最好的选择是跳过 formControlName 指令的用法并编写一些自定义验证。

改变这个:

<div class="col-sm-9">
    <input type="text" formControlName='email' class="form-control" required>
</div>  

到这里:

<div class="col-sm-9">
    <input type="text" class="form-control" required>
</div>  

【讨论】:

    猜你喜欢
    • 2020-12-05
    • 2020-09-07
    • 2019-12-01
    • 2021-01-17
    • 1970-01-01
    • 2018-07-17
    • 2021-01-12
    • 2019-07-07
    • 2017-09-27
    相关资源
    最近更新 更多