Angular2 ngIf 如果在承诺范围内发生变化则不更新
Angular2 ngIf not updated if change within promise
在我们的组件中,我们有一个上传表单和一条确认消息。
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 .
上传有效,在控制台中,我可以看到正确更改的布尔值 立即:
Uploaded a blob or file!
isFileSubmitted true
isUploadLoaderVisible false
但是在浏览器上(我使用 Chrome),视图不是 "switched" 并且 ngIf 似乎实际上看到 isFileSubmitted 现在只有在我更改 window/tab 并在非常大的延迟(30-34 秒)之后返回。 例如我的触发器的新布尔值在很长一段时间之前没有 "passed" 到组件......
也许是因为 我直接从 then()
承诺结果 更改了布尔状态?我看不出如何以与我不同的方式更改布尔值。
注意:延迟不能是上传时间造成的。由于承诺在上传完成之前不会得到解决,因此我不会看到 Uploaded
控制台日志。而我的测试文件目前是50kb。
你有什么想法吗?
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);
});
}
}
}
这是一个很好的答案:
更多信息在这里:ChangeDetectorRef
在我们的组件中,我们有一个上传表单和一条确认消息。
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 .
上传有效,在控制台中,我可以看到正确更改的布尔值 立即:
Uploaded a blob or file!
isFileSubmitted true
isUploadLoaderVisible false
但是在浏览器上(我使用 Chrome),视图不是 "switched" 并且 ngIf 似乎实际上看到 isFileSubmitted 现在只有在我更改 window/tab 并在非常大的延迟(30-34 秒)之后返回。 例如我的触发器的新布尔值在很长一段时间之前没有 "passed" 到组件......
也许是因为 我直接从 then()
承诺结果 更改了布尔状态?我看不出如何以与我不同的方式更改布尔值。
注意:延迟不能是上传时间造成的。由于承诺在上传完成之前不会得到解决,因此我不会看到 Uploaded
控制台日志。而我的测试文件目前是50kb。
你有什么想法吗?
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);
});
}
}
}
这是一个很好的答案:
更多信息在这里:ChangeDetectorRef