【问题标题】:Angular2 ngIf not updated if change within promise如果在承诺范围内更改,Angular2 ngIf 不会更新
【发布时间】:2017-04-23 23:34:25
【问题描述】:

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

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

file-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);
            });
    }
  }

}

在表单提交时,我们将触发器设置为布尔值以显示加载器。它完美而即时地工作。

然后代码提交文件(在我们的例子中是到 firebase),当承诺解决时,我将加载程序 isUploadLoaderVisible 更改为 false 并将确认消息一 isFileSubmitted 更改为 true。

上传工作正常,在控制台中,我可以看到正确更改的布尔值并且立即

上传了一个 blob 或文件!

isFileSubmitted true

isUploadLoaderVisible 错误

但是在浏览器上(我使用 Chrome),视图没有“切换”,并且 ngIf 似乎实际上看到 isFileSubmitted 现在只有当我更改窗口/选项卡并返回或在非常大的延迟后才为真(30-34 秒)。 比如我的触发器的新布尔值在很长一段时间内没有“传递”给组件......

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

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

你有什么想法吗?

【问题讨论】:

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


    【解决方案1】:
    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

    【讨论】:

    • 为什么有必要这样做?
    猜你喜欢
    • 2014-08-19
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 2014-03-28
    • 2016-12-05
    • 1970-01-01
    • 2012-12-28
    相关资源
    最近更新 更多