Фильтрация файлов в svelte

#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. Спасибо! Это сработало! И спасибо за все объяснения и терпение.