web-dev-qa-db-ja.com

Angular 5ファイルのアップロード: 'HTMLInputElement'で 'value'プロパティを設定できませんでした

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>

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

そして、私が書いて使用したカスタム検証ツールのコードは次のとおりです。

「@ 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;

    }
}

これで、入力コントロールでファイルを選択するとすぐに問題が発生し、コンソールに次のエラーメッセージが表示されます。

エラーDOMException: 'HTMLInputElement'の 'value'プロパティの設定に失敗しました:この入力要素はファイル名を受け入れます。ファイル名はプログラムでのみ空の文字列に設定できます。

このコードは以前に機能していたため、どこから始めればよいのかわかりません。どんな助けも大歓迎です!

ATTENTION:以下は有効な回答へのリンクです。 Angular2:<input type = "file" />の検証はトリガーしませんアップロードするファイルを変更するとき

8
Behrooz

エラーが言っているように、選択をクリアするには、空の文字列をファイル入力値にのみ設定できます。そうしないと、セキュリティリスクが発生する可能性があります。そのコードがどのように機能するか想像できません。たぶん、いくつかの非標準(悪い)ブラウザで?

行を削除しただけでは、そのコードは機能しません。どうせ、既に持っている入力に同じ値を設定する必要があるのはなぜですか?

編集:ファイル入力の検証にはカスタムValueAccessorが必要と思われます。別の答えの解決策: Angular2:アップロードするファイルを変更しても、<input type = "file" />の検証はトリガーされません

8
funkizer

私の場合、formControlNameを削除しました:

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

そして.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();
      };
    }
  }
2
NicuVlad

入力プロパティの値を選択したファイルに設定しないでください。代わりに、ファイルの内容を変数に設定し、リクエストオブジェクトに個別に追加するだけです。ファイルinputの場合、入力値としてeven.target.valueを割り当てるだけで、ユーザーには実際に選択されたファイルが表示されます。

2
voddy