svelte 中的文件输入不更新数据
File input in svelte does not update data
我正在尝试创建一个带有客户端文件输入的站点,其中一些数据完全在客户端处理,没有任何数据发送到服务器。
我有以下 Svelte 组件 (App.svelte):
<script>
let data;
function handleFileSelect(evt) {
var files = evt.target.files;
if (! (files && files[0])) {
return;
}
let binfile = files[0];
let reader = new FileReader();
reader.onload = function(evt) {
data = new Uint8Array(evt.target.result);
}
reader.readAsArrayBuffer(binfile);
}
</script>
<main>
<label for="fileinput">Your data</label>
<input type="file" id="fileinput" on:click={handleFileSelect}/>
<div>
<textarea id="datafield" rows="10" cols="50">{data}</textarea>
</div>
</main>
当我点击按钮时,文本区域中的数据没有更新,但是当我第二次点击按钮时,数据会在点击后立即加载到文本区域中。我是否在正确的轨道上以 svelte 加载文件?我错过了什么?谢谢!
在文件输入上您要绑定值而不是点击事件。
像这样:
<script>
let files = [];
<input
bind:files
type="file"
accept="image/*">
or bind:value={files}
{files}
编辑:回答 chovy 的问题
let template = null;
let files = null;
$: if (files) {
const fileText = files[0].text();
fileText.then((text) => {
template = text;
});
files = null;
}
请注意,我只打算在代码中使用第一个文件,如果您使用多文件上传,则必须从文件调用中删除 [0],遍历数组并写入就像处理任何其他数组数据一样,将每个单独文件的内容放入指定的变量中。在上述情况下,模板将包含实际文件数据作为文本。
希望对您有所帮助。
我也必须这样做才能获取文件的内容:
<script>
let data;
let files;
$: {
if (files && files[0]) {
let binfile = files[0];
let reader = new FileReader();
reader.onload = function(evt) {
data = new Uint8Array(evt.target.result);
}
reader.readAsArrayBuffer(binfile);
}
}
</script>
<main>
<label for="fileinput">Your data</label>
<input type="file" id="fileinput" bind:files />
<div>
<textarea id="datafield" rows="10" cols="50">{data}</textarea>
</div>
</main>
如果您想要自定义按钮而不是难看的默认按钮:
代码简洁 + Framework7
<script>
let browseInput;
let data;
let files;
$: {
if ... see answer 2
}
</script>
<input bind:this={browseInput} type="file" id="fileinput" class="hidden" bind:files={files}>
<Button onClick={() => browseInput.click()} fill raised">Open Keystore File</Button>
<style>
.hidden {
display: none !important;
}
</style>
我正在尝试创建一个带有客户端文件输入的站点,其中一些数据完全在客户端处理,没有任何数据发送到服务器。
我有以下 Svelte 组件 (App.svelte):
<script>
let data;
function handleFileSelect(evt) {
var files = evt.target.files;
if (! (files && files[0])) {
return;
}
let binfile = files[0];
let reader = new FileReader();
reader.onload = function(evt) {
data = new Uint8Array(evt.target.result);
}
reader.readAsArrayBuffer(binfile);
}
</script>
<main>
<label for="fileinput">Your data</label>
<input type="file" id="fileinput" on:click={handleFileSelect}/>
<div>
<textarea id="datafield" rows="10" cols="50">{data}</textarea>
</div>
</main>
当我点击按钮时,文本区域中的数据没有更新,但是当我第二次点击按钮时,数据会在点击后立即加载到文本区域中。我是否在正确的轨道上以 svelte 加载文件?我错过了什么?谢谢!
在文件输入上您要绑定值而不是点击事件。
像这样:
<script>
let files = [];
<input
bind:files
type="file"
accept="image/*">
or bind:value={files}
{files}
编辑:回答 chovy 的问题
let template = null;
let files = null;
$: if (files) {
const fileText = files[0].text();
fileText.then((text) => {
template = text;
});
files = null;
}
请注意,我只打算在代码中使用第一个文件,如果您使用多文件上传,则必须从文件调用中删除 [0],遍历数组并写入就像处理任何其他数组数据一样,将每个单独文件的内容放入指定的变量中。在上述情况下,模板将包含实际文件数据作为文本。
希望对您有所帮助。
我也必须这样做才能获取文件的内容:
<script>
let data;
let files;
$: {
if (files && files[0]) {
let binfile = files[0];
let reader = new FileReader();
reader.onload = function(evt) {
data = new Uint8Array(evt.target.result);
}
reader.readAsArrayBuffer(binfile);
}
}
</script>
<main>
<label for="fileinput">Your data</label>
<input type="file" id="fileinput" bind:files />
<div>
<textarea id="datafield" rows="10" cols="50">{data}</textarea>
</div>
</main>
如果您想要自定义按钮而不是难看的默认按钮: 代码简洁 + Framework7
<script>
let browseInput;
let data;
let files;
$: {
if ... see answer 2
}
</script>
<input bind:this={browseInput} type="file" id="fileinput" class="hidden" bind:files={files}>
<Button onClick={() => browseInput.click()} fill raised">Open Keystore File</Button>
<style>
.hidden {
display: none !important;
}
</style>