Ошибка приложения Svelte todo: не отображаются ошибки проверки формы

Я работаю над небольшим приложением ToDo в Svelte в учебных целях (я новичок в Svelte).

Я застрял, пытаясь добавить ошибки проверки в форму New Todo.

Внутри тегов <script> у меня

var errors = [];

function addTodo(){
    
    //Empty todo object
    let newTodo = {};
    
    //Set new todo object's properties (id, title, completed)
    if (todos.length == 0) {
        newTodo.id = 1;
    } else {
        newTodo.id = todos[0].id + 1;
    }
    
    if(document.querySelector('#new_todo').value.length < 3){
        errors.push('Please introduce at least 3 characters');
    } else {
        newTodo.title = document.querySelector('#new_todo').value;
    }
    
    newTodo.completed = false;
    
    //Add new todo
    if (errors === undefined || errors.length == 0) {
        todos.unshift(newTodo);
    }
    todos = todos;
    
    //Empty field when done adding todo
    document.querySelector('#new_todo').value = '';
}

В представлении:

{#if errors.length > 0}
    <div class="m-2 alert alert-danger">
        {#each errors as error}
            <p>{error}</p>
        {/each}
     </div>
{/if}
    
<div class="input-group p-2" id="addForm">
    <input type="text" class="form-control" id="new_todo" placeholder="New Todo">
    <div class="input-group-append">
        <button on:click="{addTodo}" class="btn btn-sm btn-success">Add</button>
    </div>
</div>

По какой-то причине, которую я не смог найти, сообщение о проверке ошибки не появляется, а на консоли отображается Uncaught (in promise): if_block0.p is not a function.

См. REPL здесь.

В чем моя ошибка?


person Razvan Zamfir    schedule 30.06.2020    source источник


Ответы (2)


Вам нужно уведомить Svelte об изменении массива errors:

errors.push('Please introduce at least 3 characters')
errors = errors

Svelte не отслеживает мутации объектов, а только присваивания (т.е. =). Но я думаю, вы это уже знаете, поскольку у вас уже есть аналогичный код в вашем компоненте.

При этом я думаю, что обнаруженная вами ошибка может считаться ошибкой в ​​Svelte. Но это, вероятно, не влияет на полезный вариант использования - то есть на изменение реактивной переменной, но не на то, чтобы изменение отражалось в Svelte.

Кроме того, это не связано, но я настоятельно рекомендую не использовать ключевое слово var для переменных в любом написанном сегодня JS-коде, но особенно в компоненте Svelte, где это может сбить с толку, хотите ли вы, чтобы он был реактивным (let) или нет (const).

ИЗМЕНИТЬ

Вам, вероятно, также следует полагаться на Svelte для доступа к значению вашего поля ввода вместо использования document.querySelector.

Что-то вроде этого:

<script>
  ...

  let newTodoValue = ''

  const addTodo = () => {
    if (newTodoValue.length < 3) {
      errors.push('Too short')
      errors = errors
    }

    ...
    
    // clear the value
    newTodoValue = ''
  }
</script>

<input type="text" class="form-control" bind:value={newTodoValue} />

Вам очень редко нужно использовать DOM API (например, querySelector) непосредственно в декларативных фреймворках, таких как Svelte. Если вам нужен доступ к самому элементу, обычно лучше использовать bind:this или действие в Svelte.

person rixo    schedule 30.06.2020
comment
Хороший улов. В свой ответ я добавил несколько общих советов. - person rixo; 01.07.2020

Проблема полностью решена, если заменить

if(document.querySelector('#new_todo').value.length < 3){
    errors.push('Please introduce at least 3 characters');
} else {
    newTodo.title = document.querySelector('#new_todo').value;
}

с участием

if(document.querySelector('#new_todo').value.length < 3){
    errors.push('Please introduce at least 3 characters');
    errors = errors; // new line
} else {
    newTodo.title = document.querySelector('#new_todo').value;
    errors = []; // new line
}
person Razvan Zamfir    schedule 30.06.2020