0

In unserer Komponente haben wir ein Upload-Formular und eine Bestätigungsmeldung.Angular2 ngIf nicht aktualisiert, wenn Änderung innerhalb des Versprechens

Datei-form.component.html

<div class="tab-pane active" id="upload"> 
    <div id="loader-wrapper" *ngIf="isUploadLoaderVisible"> 
     <div id="loader"></div> 
     <p class="text-center">Uploading</p> 
    </div> 
    <div *ngIf="!isFileSubmitted"> 
     <form class="form-horizontal" [formGroup]="fileUploadForm" (ngSubmit)="onSubmit()"> 
     <input type="file" id="file" formControlName="file" (change)="fileChangeEvent($event)"> 
     </form> 
    </div> 
    <div *ngIf="isFileSubmitted"> 
     <p class="alert alert-success"> 
      <i class="fa fa-check"></i> 
      Thanks for upload. 
     </p> 
     <p><a class="btn btn-default" [routerLink]="['..']">Back</a></p> 
    </div> 
</div> 

Datei-form.component.ts

import { Component, OnInit, Inject } from '@angular/core'; 
import { 
    FormGroup, 
    Validators, 
    FormBuilder, 
    FormControl 
} from '@angular/forms'; 
import { AngularFire, FirebaseApp } from 'angularfire2'; 

@Component({ 
    selector: 'app-file-form', 
    templateUrl: './file-form.component.html', 
    styleUrls: ['./file-form.component.css'] 
}) 
export class SfFileFormComponent implements OnInit { 
    // States togglers 
    isFileSubmitted: boolean = false; 
    isUploadLoaderVisible: boolean = false; 

    // Declarations 
    fileUploadForm: FormGroup; 
    uploadedFile; 
    isFileValid: boolean = false; 
    uploadedCorrectedFilename: string; 

    constructor(private formBuilder: FormBuilder, 
    public af: AngularFire, 
    @Inject(FirebaseApp) private firebaseApp: firebase.app.App) { } 

    ngOnInit() { 
    this.initForm(); 
    } 

    private initForm() { 
    let file = ''; 

    this.fileUploadForm = this.formBuilder.group({ 
     file: file 
    }); 
    } 

    fileChangeEvent(fileInput: any) { 
    this.uploadedFile = fileInput.target.files; 
    let fileType: string = _.toLower(this.uploadedFile[0].type); 

    if (fileType === 'application/pdf') { 
     this.isFileValid = true; 
     console.log('File is valid. Click to upload file', this.uploadedFile[0]); 
    } else { 
     this.isFileValid = false; 
     this.fileUploadForm.reset(); 
     console.log('File is invalid. Cancel Upload and block form submission', this.uploadedFile[0]); 
    } 
    } 

    onSubmit() { 
    if (this.uploadedFile.length === 1) { 
     let file: FileList = this.uploadedFile[0]; 
     console.log('Uploading File', file); 

     this.isUploadLoaderVisible = true; 

     // Upload to Firebase 
     this.firebaseApp 
     .storage() 
     .ref() 
     .child('filesdummy/' + file.name) 
      .put(file) 
      .then((snapshot) => { 
       console.log('Uploaded a blob or file!'); 

       this.isUploadLoaderVisible = false; 
       this.isFileSubmitted = true; 
       console.log('isFileSubmitted',this.isFileSubmitted); 
       console.log('isUploadLoaderVisible', this.isUploadLoaderVisible); 
      }); 
    } 
    } 

} 

Bei Formular abgesendet haben, setzen wir unsere Trigger boolean zeige den Lader an. Es funktioniert perfekt und sofort.

Der Code senden Sie dann die Datei (in unserem Fall Firebase) und wenn das Versprechen verrechnet wird, ändere ich den Lader isUploadLoaderVisible zu false und Bestätigungsmeldung eine isFileSubmitted auf True.

Die Upload-Werke und in der Konsole, kann ich sehen, wo booleans richtig und sofort geändert:

einen Klecks hochgeladen oder eine Datei!

isFileSubmitted wahr

isUploadLoaderVisible falsch

Aber Browser (ich benutze Chrome), die Ansicht nicht "eingeschaltet" und die ngIf scheint tatsächlich zu sehen, die isFileSubmitted ist jetzt nur wahr, wenn i Fenster/Tab wechseln und zurückkommen oder nach einer sehr großen Verzögerung (30-34 Sek.). wie der neue boolean Wert meines Trigger, wo nicht „bestanden“, um die Komponente vor langer Zeit ...

Vielleicht ist es, weil ich die Booleschen Zustände direkt aus dem then() Versprechen Ergebnis ändern? Ich sehe nicht, wie ich die Booleschen Werte anders ändern kann als ich.

Hinweis: Die Verzögerung kann nicht durch das Hochladen der Zeit verursacht werden. Da das Versprechen nicht aufgelöst werden würde, bis das Hochladen abgeschlossen ist, würde ich das Uploaded Konsolenprotokoll nicht sehen. Und meine Testdatei ist derzeit 50kb.

Haben Sie eine Idee?

Antwort

2
import { Component, OnInit, Inject, ChangeDetectorRef } from '@angular/core'; 

export class SfFileFormComponent implements OnInit { 
    constructor(private formBuilder: FormBuilder, 
     public af: AngularFire, 
     @Inject(FirebaseApp) private firebaseApp: firebase.app.App, 
     private ref: ChangeDetectorRef) { } 
    } 

    onSubmit() { 
     if (this.uploadedFile.length === 1) { 
      let file: FileList = this.uploadedFile[0]; 
      console.log('Uploading File', file); 

      this.isUploadLoaderVisible = true; 

      // Upload to Firebase 
      this.firebaseApp 
      .storage() 
      .ref() 
      .child('filesdummy/' + file.name) 
       .put(file) 
       .then((snapshot) => { 
        console.log('Uploaded a blob or file!'); 

        this.isUploadLoaderVisible = false; 
        this.isFileSubmitted = true; 
        this.ref.detectChanges(); 
        console.log('isFileSubmitted',this.isFileSubmitted); 
        console.log('isUploadLoaderVisible', this.isUploadLoaderVisible); 
       }); 
     } 
    } 

} 

Hier ist eine gute Antwort: triggering-angular2-change-detection-manually

Mehr Infos hier: ChangeDetectorRef

+1

Warum ist das notwendig? –

Verwandte Themen