在我们的组件中,我们有一个上传表单和一条确认消息。
文件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。
你有什么想法吗?
答案 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