Ошибка приложения 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 здесь.
Где моя ошибка?
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.
Проблема полностью решена, если заменить
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
}