我有一个Aurelia文件上传控制器,我想观察添加到数组progress
的任何对象的uploadedFiles
属性。首先,我的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
订阅有什么问题吗?
答案 0 :(得分:1)
在上传进度时,您需要确保它可以通过浏览器进行跟踪。其次,uploadRequest
HttpService
中的updateProgress
不会保留执行上下文,这意味着UploadedFile
不会在this.httpClient.uploadRequest('files', file, () => uploadedFile.updateProgress() })
.then((httpResponse) => {
// File uploaded successfully!
});
类的正确实例上调用android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
。可能你需要做这样的事情:
@Override
public void onCreate() {
super.onCreate();
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}