2017-09-24 2 views
0

이온 및 각도를 사용하여 모바일 앱을 구축하고 있습니다. 파일 다운로드를 위임 할 서비스를 만들었습니다. 이 서비스는 파일을 다운로드 할 때 내 구성 요소가 관찰 할 수있는 부분을 생성합니다. 구성 요소가 예상대로 이벤트를 받으면 콘솔에서 데이터를 볼 수 있지만 다운로드가 완료 될 때까지 템플릿보기가 업데이트되지 않습니다. 이상하게도 뷰를 업데이트하는 앱 메뉴를 토글하려고하면 충분합니다.구성 요소가 관찰 가능 상태에서 데이터를 수신하지만보기가 업데이트되지 않습니다.

서비스 콘솔에서

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 "doSync"가 실행되는 동안 : 여기

은 관련 코드입니다

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 

VIEW

<progress-bar [progress]="progressStatus"></progress-bar> 

<div class="progress-outer"> 
    <div class="progress-inner" [style.width]="progress + '%'"> 
     {{ progress }}% 
    </div> 
</div> 
+2

당신이 비동기 파이프를 사용하는 대신 progressStatus''의 진행 상황을 저장하는 시도? 또 다른 방법은'ChangeDetectorRef'를 삽입하고'markForCheck'를 호출하는 것입니다. – Everest

+0

@Everest 안녕하세요, 여러분의 sugestion에 감사드립니다. 나는 ChangeDetectorRef.detectChanges()를 사용하여 종료했다. –

답변

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); 
    }); 
관련 문제