繁体   English   中英

Aurelia BindingEngine属性观察者不会触发

[英]Aurelia BindingEngine propertyObserver does not fire

我有一个Aurelia文件上传控制器,在这里我想观察添加到数组uploadedFiles数组中任何对象的progress属性。 首先,我的HTML模板如下所示:

<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!
          });
      }
    }
  }
}

我这样做是因为进度更新来自外部事件,因此从控制器到模板的绑定无法立即使用(因为出于性能方面的原因并不是每个对象都被观察到)。

这是UploadedFile类:

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 + ' %.');
  }
}

这是上传请求的样子(请注意withProgressCallback行):

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订阅出了什么问题吗?

在上传进度时,您需要确保浏览器可以跟踪它。 其次,您在HttpService中的uploadRequest不会保留执行上下文,这意味着不会在UploadedFile类的正确实例上调用updateProgress 可能您需要执行以下操作:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM