it-swarm.com.de

Angular 5 Datei-Upload: Fehler beim Festlegen der Eigenschaft 'value' für 'HTMLInputElement'

Ich habe ein Formular zum Hochladen einer Datei in einer eckigen 5-App. Da ich sie genau aus einem Code kopiert habe, den ich vor einiger Zeit geschrieben hatte, kann ich schwören, dass sie zuvor funktioniert hat. 

Hier ist mein HTML-Code:

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

Hier ist die "onFileChange" -Methode, die im fileUpload-Steuerelement verwendet wird:

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

und hier ist der Code für den benutzerdefinierten Validator, den ich geschrieben und verwendet habe:

importieren {FormControl} aus '@ angle/forms';

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;

    }
}

Nun ist das Problem, sobald ich eine Datei in der Eingabesteuerung auswähle, erhalte ich diese Fehlermeldung in der Konsole:

ERROR DOMException: Die 'value'-Eigenschaft für .__ konnte nicht festgelegt werden. 'HTMLInputElement': Dieses Eingabeelement akzeptiert einen Dateinamen, der .__ sein kann. nur programmgesteuert auf die leere Zeichenfolge gesetzt werden.

Dieser Code hat schon einmal funktioniert, daher habe ich keine Ahnung, wo ich überhaupt anfangen soll. Jede Hilfe wird geschätzt!

ACHTUNG: Hier ist ein Link zu einer funktionierenden Antwort: Angular2: Validierung für <input type = "file" /> wird nicht ausgelöst, wenn die Datei in upload geändert wird

1

Wie der Fehler besagt, können Sie eine leere Zeichenfolge nur auf einen Dateieingabewert setzen, um die Auswahl zu löschen. Andernfalls könnten Sicherheitsrisiken entstehen. Ich kann mir nicht vorstellen, wie dieser Code jemals funktionieren konnte. Vielleicht in einem nicht standardmäßigen (schlechten) Browser? 

Sollte der Code nicht funktionieren, wenn Sie nur die Zeile entfernen, warum müssen Sie den gleichen Wert auf die Eingabe setzen, die bereits vorhanden ist?

Bearbeiten: Anscheinend wird ein benutzerdefinierter ValueAccessor für die Überprüfung von Dateieingaben benötigt. Lösung in einer anderen Antwort: Angular2: Validierung für <input type = "file" /> wird nicht ausgelöst, wenn die Datei in Upload geändert wird

3
funkizer

In meinem Fall habe ich gerade den formControlName entfernt:

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

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

Setzen Sie den Wert der Eingabeeigenschaft nicht auf die ausgewählte Datei. Setzen Sie stattdessen einfach den Dateiinhalt in eine Variable und hängen Sie ihn separat an das Anforderungsobjekt an. Weisen Sie für die Dateieingabe einfach den Wert even.target.value als Eingabewert zu, damit der Benutzer die tatsächlich ausgewählte Datei sieht.

2
voddy