#file #filtering #svelte
Вопрос:
недавно я следил за некоторыми сообщениями в stack overflow об импорте некоторых файлов в svelte, и это код:
<script>
let files = [];
function contentArray(ev){
files = [...files, ...ev.target.files.filter(f => !files.includes(f))]
}
</script>
<input type='file' multiple on:change={contentArray} accept=".txt">
{#each files as file}
<p>The imported file is: {file.name}</p>
{#await file.text() then text}
<pre>{text}</pre>
{/await}
{/each}
Моя цель-когда я импортирую файл, если я попытаюсь импортировать его снова, программа просто не покажет его. Я пробовал использовать этот filter
метод, но он выдает мне эту ошибку:
ev.target.files.filter is not a function or its return variable is not iterable
Я немного поискал в Интернете, но не могу понять, где я ошибся.
Заранее спасибо.
Ответ №1:
ev.target.files
является не массивом, а FileList
(документы списка файлов в MDN) и, как таковой, не имеет filter()
метода.
Итак, чтобы использовать filter()
, вы должны сначала преобразовать его FileList
в массив, который вы можете сделать следующим образом:
let arrayFileList = [...ev.target.files];
// now you can arrayFileList.filter(...)
Кроме того, сравнение File
объектов, когда вы это делаете !files.includes(f)
, может не дать вам желаемого результата в зависимости от ваших настроек. Таким образом, вы все равно можете получить один и тот же файл несколько раз. Это связано с тем , что при добавлении одного и того же файла несколько раз в ваш <input type="file">
, соответствующие File
экземпляры могут быть разными. Поэтому вы, возможно, захотите сравнить на основе имени, как в
arrayFileList.filter(f => !files.some(ff => ff.name === f.name));
Комментарии:
1. Хорошо, спасибо за помощь, но если я импортирую файл с именем «test1», затем «test2» и снова «test1», я дважды увижу содержимое «test1″… как я могу это решить?
2. Вы пробовали все мои предложения, особенно последнее, в котором сравнивается имя?
3. Да, но, может быть, я где-то ошибся… вот программа прямо сейчас: svelte.dev/repl/9304e104d7f94f1498f47269e3671c80?версия=3.38.2 (так что вы можете запустить и отредактировать ее, если хотите)
4. Здорово, что вы использовали repl. Там была пара жучков. Исправлена версия здесь . Самая важная ошибка:
filter()
не изменяет массив, для которого он вызывается, он возвращает новый отфильтрованный массив. И я исправил вероятность тогоFile.text()
, что один и тот же файл будет вызываться несколько раз при повторной визуализации.5. Спасибо! Это сработало! И спасибо за все объяснения и терпение.