Angular 5文件上传:无法在“ HTMLInputElement”上设置“ value”属性

Beh*_*ooz 8 html forms input angular angular5

我有一个用于在angular 5应用程序中上载文件的表单,并且由于我完全是从前一阵子编写的代码中复制出来的,所以我可以保证它以前曾经工作过。

这是我的HTML代码:

<form [formGroup]="form" (ngSubmit)="onSubmit()">
        <div class="form-group">
            <label>File:</label>
            <input #theFile type="file" (change)="onFileChange($event)" accept=".png" class="form-control" 
                    formControlName="content" />
            <input type="hidden" name="fileHidden" formControlName="imageInput"/>

                    <!-- [(ngModel)]="model.content" -->

            <div class="alert alert-danger" *ngIf="!form.prestine && form.controls.content.errors?.noFile">
                Please provide a photo.
            </div>
            <div class="alert alert-danger" *ngIf="form.controls.content.errors?.fileTooBig">
                The file is too big and won't uploaded. Maximum allowed size is 500kb.
            </div>
        </div>
        <div class="form-group">
            <label>Notes</label>
            <textarea type="text" class="form-control" formControlName="notes" [(ngModel)]="model.notes" > </textarea>
        </div>
        <button type="submit" class="btn btn-primary" [disabled]="!form.valid">Submit</button>
        <button class="btn btn-default" type="button" (click)="close(false);">Cancel</button>
    </form>
Run Code Online (Sandbox Code Playgroud)

这是fileUpload控件中使用的“ onFileChange”方法:

onFileChange($event)
  {
    if ($event.target.files.length > 0)
    {
        let ftu: File = null;
        ftu = $event.target.files[0];
        this.form.controls['content'].setValue(ftu);
        this.model.content = $event.target.files[0];
    }
  }
Run Code Online (Sandbox Code Playgroud)

这是我编写和使用的自定义验证器的代码:

从“ @ angular / forms”导入{FormControl};

export class SekaniRootImageValidators
{
    static sizeTooBig(control: FormControl)
    {
        if (!control.value)
        {
            return { noFile : true }
        }
        else  if (control.value[0].size > 505000)
        {
            return { fileTooBig: true}
        }
        return null;

    }
}
Run Code Online (Sandbox Code Playgroud)

现在的问题是,一旦在输入控件中选择一个文件,我就会在控制台中收到以下错误消息:

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

这段代码以前工作过,所以我什至不知道从哪里开始。任何帮助表示赞赏!

注意:这是一个可行答案的链接:Angular2:更改要上传的文件时,不会触发对<input type =“ file” />的验证

Nic*_*lad 19

就我而言,我只是删除了 formControlName:

<input type="file" (change)="onFileChange($event)">
Run Code Online (Sandbox Code Playgroud)

和.ts:

onFileChange(event) {
    const reader = new FileReader();

    if (event.target.files && event.target.files.length) {
      const [file] = event.target.files;
      reader.readAsDataURL(file);
      reader.onload = () => {
        this.data.parentForm.patchValue({
          tso: reader.result
        });

        // need to run CD since file load runs outside of zone
        this.cd.markForCheck();
      };
    }
  }
Run Code Online (Sandbox Code Playgroud)


ali*_*are 10

首先,您应该从类型文件的元素中删除“formControlName”,因为它获取的是字符串,然后在您的 ts 文件中您应该添加这个

if (event.target.files && event.target.files.length > 0) {
  const file = (event.target.files[0] as File);
  this.yourForm.get('image').setValue(file);
  console.log(this.yourForm.get('image').value);
}
Run Code Online (Sandbox Code Playgroud)

  • 从元素中删除“formControlName”解决了我的问题。谢谢! (3认同)

fun*_*zer 8

就像错误所说的一样,您只能将空字符串设置为文件输入值以清除选择。否则可能会带来安全风险。我无法想象该代码将如何工作。也许在某些非标准(错误的)浏览器中?

如果仅删除该行,该代码不起作用,为什么还需要为它已经具有的输入设置相同的值?

编辑:似乎需要一个自定义ValueAccessor来验证文件输入。另一个答案的解决方案:Angular2:更改要上传的文件时,不会触发对<input type =“ file” />的验证

  • 谷歌一下,似乎不支持文件输入。您至少需要添加一个自定义ValueAccessor。这个答案可能会有所帮助:/sf/ask/2932256911/#41938495 (3认同)

jam*_*ace 5

通过为文件提供 2 个输入来实现此目的。我是这样做的:

  this.myForm= this.formBuilder.group({
      fileSource: ['', Validators.required],
      fileName: '',
    })
Run Code Online (Sandbox Code Playgroud)

超文本标记语言

<input type="file" formControlName='fileSource' (change)="onFileSelected($event)"/>
Run Code Online (Sandbox Code Playgroud)

打字稿

  onFileSelected(event) {
    if(event.target.files.length > 0) 
     {
       this.myForm.patchValue({
          fileName: event.target.files[0],
       })
     }
  }

submit(){
    const formData = new FormData();
    formData.append('file', this.myForm.get('fileName').value);
   
    this.http.post('http://localhost:3000/upload', formData)
      .subscribe(res => {
        console.log(res);
        alert('Uploaded Successfully.');
      })
  }
Run Code Online (Sandbox Code Playgroud)