我正在使用离子和角度构建移动应用。我创建了一个委托下载文件的服务。在下载文件时,此服务会创建我的组件观察到的可观察对象。组件按预期接收事件,我可以在控制台中看到数据,但模板视图在下载完成之前不会更新。奇怪的是,如果我尝试切换应用程序菜单,视图会获得更新。
以下是相关代码:
SERVICE
import {Injectable} from '@angular/core';
import {FileTransfer, FileTransferObject} from "@ionic-native/file-transfer";
import {BehaviorSubject} from "rxjs/BehaviorSubject";
@Injectable()
export class DataRetriever {
protected fileTransfer: FileTransferObject = this.transfer.create();
protected _progressSource = new BehaviorSubject<number>(0);
protected progressStep = 0;
progress$ = this._progressSource.asObservable();
/**
* Trigger the progress observable
* @param {ProgressEvent} progressEvent
*/
listener(progressEvent:ProgressEvent) {
if (progressEvent.lengthComputable) {
let progress = Math.round((progressEvent.loaded / progressEvent.total)*100);
if(progress > this.progressStep){
console.log("Download progress " + progress + "%");
this.progressStep++;
this._progressSource.next(progress);
}
} else {
this._progressSource.next(1);
}
}
/**
* Perform sync data download
* @returns {Promise<boolean>}
*/
public doSync() {
this.fileTransfer.onProgress((event) => this.listener(event));
return this.getLastUpdate().then(updated_at => {
if(updated_at === 0){
let filename = 'first_sync.zip';
return this.downloadFirstSync().then(()=>{
return this.file.checkFile(this.file.dataDirectory,filename);
}).then((exists) => {
console.log("Success? " + (exists ? "Y" : "N"));
}).catch(error=>{
console.log(JSON.stringify(error,null,2))
});
}
});
}
/**
* Download first sync file
*/
downloadFirstSync() {
const url = this.api.getApiURL('first_sync');
let filename = 'first_sync.zip';
return this.fileTransfer
.download(url, this.file.dataDirectory + filename,true,Api.getApiHeader(this.token))
.then((entry) => {
console.log('Download complete: ' + entry.toURL());
return Promise.resolve();
}).catch(error => {
console.log(JSON.stringify(error,null,2));
return Promise.reject(error);
});
}
}
COMPONENT
import {Component} from '@angular/core';
import {DataRetriever} from "../../providers/data-retriever/data-retriever";
import {Subscription} from "rxjs/Subscription";
@Component({
selector: 'page-data-retrieve',
templateUrl: 'data-retrieve.html'
})
export class DataRetrievePage {
public updated_at:number = 0;
public progressStatus = 0;
protected progressSubscription: Subscription;
constructor(public navCtrl: NavController,
public dataRetriever:DataRetriever) {
}
ionViewDidLoad() {
this.progressSubscription = this.dataRetriever.progress$.subscribe(
amount => {
console.log('Update received ' + amount);
this.progressStatus = amount;
},error => {
console.log(error);
});
this.dataRetriever.getLastUpdate().then(result=>{
this.updated_at = result;
});
console.log('ionViewDidLoad DataRetrievePage');
}
doSync(){
this.dataRetriever.doSync();
}
ngOnDestroy() {
this.progressSubscription.unsubscribe();
}
}
LOG来自控制台,而#34; doSync&#34;正在运行:
Download progress 1% data-retrieve.ts:34
Update recebido 1 data-retriever.ts:59
Download progress 2% data-retrieve.ts:34
Update recebido 2 data-retriever.ts:59
Download progress 3% data-retrieve.ts:34
Update recebido 3 data-retriever.ts:59
Download progress 4% data-retrieve.ts:34
查看
<progress-bar [progress]="progressStatus"></progress-bar>
<div class="progress-outer">
<div class="progress-inner" [style.width]="progress + '%'">
{{ progress }}%
</div>
</div>
答案 0 :(得分:0)
经过大量的研究和失去的头发后,我找到了解决方案。
问题的主要原因是Angular监视用户事件并在需要时刷新视图。如果事件是系统生成的,则不会更新视图。这就是为什么你需要通知角度需要刷新的原因。
所以我将以下代码添加到我的组件中:
this.downloadProgressSubscription = this.dataRetriever.progress$.subscribe(
(info:ProgressContainer) => {
console.log(JSON.stringify(info,null,2));
this.downloadProgress = info;
this.ref.detectChanges(); // <- Relevant line
},error => {
console.log(error);
});