2017-12-23 7 views
0

私はuploadedFilesに追加されたオブジェクトのprogressプロパティを監視したいAureliaファイルアップロードコントローラを持っています。まず、私のHTMLテンプレートは次のようになります:Aurelia BindingEngine propertyObserverが起動しない

<input type="file" name="files" files.bind="fileList" multiple change.delegate="fileSelected($event)" /> 

これはコントローラ(簡体字)です。ユーザーがファイルを選択すると、fileSelectedメソッドが起動します。

import {BindingEngine, inject} from 'aurelia-framework'; 
import {HttpService} from '../../services/http-service'; 
import {UploadedFile} from '../../models/uploaded-file'; 

@inject(BindingEngine) 
export class FileUploader { 
    httpClient: HttpService; 
    fileList: FileList; 
    uploadedFiles: UploadedFile[]; 

    constructor(bindingEngine) { 
    this.bindingEngine = bindingEngine; 
    this.httpClient = new HttpService(); 
    this.uploadedFiles = []; 
    } 

    fileSelected(): void { 
    if (this.fileList) { 
     // Convert the FileList object into an array of UploadedFile objects because the Aurelia template engine cannot iterate over a 'FileList' object with 'repeat.for'. 
     for (let i = 0; i < this.fileList.length; i++) { 
     let file = this.fileList.item(i); 
     let uploadedFile = new UploadedFile(); 
     uploadedFile.file = file; 

     // Subscribe to changes of the 'progress' property of every UploadedFile. 
     uploadedFile.subscription = this.bindingEngine 
      .propertyObserver(uploadedFile, 'progress') 
      .subscribe((newValue, oldValue) => { 
      console.log('Progress changed from ' + oldValue + ' to ' + newValue); 
      }); 

     this.uploadedFiles.push(uploadedFile); 

     // Start off the file upload itself. 
     this.httpClient.uploadRequest('files', file, uploadedFile.updateProgress) 
      .then((httpResponse) => { 
      // File uploaded successfully! 
      }); 
     } 
    } 
    } 
} 

進捗状況の更新は外部イベントから来ていると(いないすべてのオブジェクトは、パフォーマンス上の理由から観察されているため)ので、バックテンプレートにコントローラからの結合は、箱から出して動作しないので、私はこれを行います。 (withProgressCallbackラインに注意してください)

ここ
export class UploadedFile { 
    file: File; 
    uploaded: boolean; 
    totalBytes: number; 
    uploadedBytes: number; 
    progress: number; 
    subscription: any; 

    constructor() { 
    this.uploaded = false; 
    this.progress = 0; 
    } 

    updateProgress(event: ProgressEvent) { 
    this.totalBytes = event.total; 
    this.uploadedBytes = event.loaded; 

    this.progress = this.uploadedBytes/this.totalBytes * 100; 
    console.log('Progress is ' + this.progress + ' %.'); 
    } 
} 

がアップロード要求は次のようになります:ここで

UploadedFileクラスだ

import {HttpClient} from 'aurelia-http-client'; 

export class HttpService { 
    backendUrl: string; 
    httpClient: HttpClient; 

    constructor() { 
    // ... 
    } 

    uploadRequest(url: string, file: File, progressCallback: any): Promise<any> { 
    let formData = new FormData(); 
    formData.append('file', file); 

    return this.httpClient.createRequest(url) 
     .asPost() 
     .withContent(formData) 
     .withCredentials(true) 
     .withProgressCallback(progressCallback) // This adds the progress callback. 
     .send(); 
    } 
} 

は、今私がいるので、間違ってやっている、明らかに何かがありますUploadedFileクラスのブラウザコンソールで進行状況の更新を見ることはできますが、プロパティの変更イベントは発生しません。

propertyObserverサブスクリプションで何が問題なのか教えていただけますか?

答えて

1

アップロードの進捗状況については、ブラウザで確認できるようにする必要があります。第2に、uploadRequestHttpServiceは実行コンテキストを保持しません。つまり、UploadedFileクラスの正しいインスタンスでupdateProgressが呼び出されません。おそらく、あなたはこのような何か実行する必要があります。それだ

this.httpClient.uploadRequest('files', file,() => uploadedFile.updateProgress() }) 
     .then((httpResponse) => { 
     // File uploaded successfully! 
     }); 
+0

を、クロージャが 'progress'プロパティは'にUploadedFileに設定されていなかった理由です、代わりに '' UploadedFile'コンテキストの対象XMLHttpRequest'に実行されました'。ありがとうございました! – thomaskonrad

+0

ところで、私はその場合にプロパティオブザーバが必要ないことも分かりました。プロパティはAureliaによって自動的に観察されます。 – thomaskonrad

関連する問題