Angular2 ng如果在承诺范围内变更,则不会更新

时间:2016-12-08 16:32:00

标签: angular firebase angular-promise es6-promise firebase-storage

在我们的组件中,我们有一个上传表单和一条确认消息。

  

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

文件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);
            });
    }
  }

}

在表单提交时,我们设置触发器boolean来显示加载器。它完美而即时地工作。

代码然后提交文件(在我们的案例中为firebase),当promise解析时,我将加载器isUploadLoaderVisible更改为false,并将确认消息一isFileSubmitted更改为true。 / p>

上传有效,在控制台中,我可以看到正确更改的布尔值和立即

  

上传了一个blob或文件!

     

isFileSubmitted true

     

isUploadLoaderVisible false

但是在浏览器上(我使用Chrome),视图没有“切换”,并且ngIf似乎实际上看到isFileSubmitted现在只有在我更改窗口/标签然后返回或经过非常大的延迟后才会生效(30-34秒)。例如我的触发器的新布尔值,在很长一段时间之前没有“传递”到组件......

也许是因为我直接从then()承诺结果更改布尔状态?我不知道如何以与我不同的方式改变布尔值。

注意:上传时间不能导致延迟。由于承诺在上传完成之前无法解决,因此我不会看到Uploaded控制台日志。我的测试文件目前是50kb。

你有什么想法吗?

1 个答案:

答案 0 :(得分: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);
                });
        }
    }

}

这是一个很好的答案: triggering-angular2-change-detection-manually

此处有更多信息:ChangeDetectorRef