我实现了一个自定义控件,它基本上是一个专门用于图像的样式文件上传器,可以预览图像。问题是我经历了一个奇怪的行为:常规HTML <input type="file">
绑定到的属性的setter在FF 53,IE 11,Edge 38中被调用两次,但在Chrome 57中没有。我不知道为什么会发生这种情况,或许你们中的一些人经历过类似的行为并且知道解决方案。
标记如下:
<template>
<!-- markup for preview functionality, irrelevant here -->
<input type="file" class="sr-only" id="${id}" aria-describedby="${id}-help" multiple accept="image/*" files.bind="imageGroup" />
<label class="btn btn-default btn-sm" aria-hidden="true" for="${id}" role="button">
<i class="fa fa-plus" aria-hidden="true"></i> Add files
</label>
</template>
支持TypeScript代码:
import { bindable, bindingMode, autoinject } from 'aurelia-framework';
import { DialogService } from 'aurelia-dialog';
import { Confirm } from '../confirm';
@autoinject
export class ImageUploader {
@bindable({ defaultBindingMode: bindingMode.twoWay }) imageArray: Array<File> = null;
@bindable id: string = null;
@bindable maxImageCount: number = 10;
@bindable maxFileSizeKiloBytes: number = 2048;
constructor(private dialogService: DialogService) { }
idChanged(newValue: string) {
if (!newValue) {
throw Error('The id parameter needs a value in order to make the file uploader work.');
}
}
set imageGroup(fileList: FileList) {
console.log('imageGroup');
if (!fileList || !fileList.length) return;
if (!this.imageArray) return;
for (let i = 0; i < fileList.length; ++i) {
let file = fileList.item(i);
if (this.imageArray.length >= this.maxImageCount) {
// TODO: Alert: maximum number of images reached
} else {
if (file && file.type.startsWith('image/')) {
// Size is in bytes. Div by 1024 to get kilobytes.
if (file.size / (1024) > this.maxFileSizeKiloBytes) {
// TODO: Alert: Image file too large.
} else {
this.imageArray.push(file);
}
} else {
// TODO: Alert: unsupported media type.
}
}
}
}
}
正如你所看到的,我使用“隐藏默认文件上传器并设置绑定标签的样式”来设置上传者本身的样式 - 我只是这样说,我已经检查过是否可能这是原因,但事实并非如此,如果我显示默认文件上传器并使用它,则可以体验相同的行为。
您还可以看到我已将<input type="file">
绑定到仅限setter的属性。我已经这样做了,因为这个属性基本上只是一个代理,它填充另一个数组(不在控件中,这是绑定到控件的),这是必要的,因为我需要允许用户多次上传文件以便他可以从不同的文件夹中选择文件。
其余的代码是无关紧要的,因为每当我选择一些文件时,console.log
行都会运行两次,所以错误位于这里的某个地方 - 我只是无法确切地知道导致这种情况发生的原因。
感谢任何帮助。
答案 0 :(得分:1)
我确认在这种情况下使用setter导致在FF中调用你的setter两次,aurelia为每个需要观察的属性创建了另一个setter。但是,您可以使用observable以最小的更改实现相同的行为,并且在这种情况下也提供封装。看看那些gist.run链接。更多信息here。
<强>更新强>
对于Firefox,它仍然以bug打开。但使用change.delegate
作为elefantino和abemeister的解决方法说可以在FF上工作,请参阅gist here。