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>