gpt4 book ai didi

javascript - Aurelia BindingEngine propertyObserver 不触发

转载 作者:行者123 更新时间:2023-12-03 02:49:28 26 4
gpt4 key购买 nike

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

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

这是 Controller (简化的)。当用户选择文件时,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!
});
}
}
}
}

我这样做是因为进度更新来自外部事件,因此从 Controller 到模板的绑定(bind)不能开箱即用(因为出于性能原因,并非每个对象都会被观察到)。

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

最佳答案

当涉及到上传进度时,您需要确保浏览器可以跟踪它。其次,你的uploadRequestHttpService不保留执行上下文,这意味着 updateProgress不会在 UploadedFile 的正确实例上调用类(class)。也许你需要做这样的事情:

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

关于javascript - Aurelia BindingEngine propertyObserver 不触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47953277/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com