Svelte todo 应用程序错误:不显示表单验证错误
Svelte todo app bug: form validation errors do not show up
出于学习目的,我正在使用 Svelte 开发一个小型 ToDo 应用程序(我是 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 here。
我的错误在哪里?
您需要将 errors
数组的更改通知 Svelte:
errors.push('Please introduce at least 3 characters')
errors = errors
Svelte 不跟踪对象突变,仅跟踪分配(即 =
)。但我想您已经知道了,因为您的组件中已经有类似的代码。
话虽如此,我认为您遇到的错误可能被视为 Svelte 中的错误。但这可能不会影响有用的用例——即改变反应变量,但不希望 Svelte 反映更改。
此外,不相关,但我强烈建议不要在今天编写的任何 JS 代码中对变量使用 var
关键字,尤其是在 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} />
您很少需要直接在 Svelte 等声明式框架中使用 DOM API(例如 querySelector
)。如果您需要访问元素本身,通常 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
}
出于学习目的,我正在使用 Svelte 开发一个小型 ToDo 应用程序(我是 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 here。
我的错误在哪里?
您需要将 errors
数组的更改通知 Svelte:
errors.push('Please introduce at least 3 characters')
errors = errors
Svelte 不跟踪对象突变,仅跟踪分配(即 =
)。但我想您已经知道了,因为您的组件中已经有类似的代码。
话虽如此,我认为您遇到的错误可能被视为 Svelte 中的错误。但这可能不会影响有用的用例——即改变反应变量,但不希望 Svelte 反映更改。
此外,不相关,但我强烈建议不要在今天编写的任何 JS 代码中对变量使用 var
关键字,尤其是在 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} />
您很少需要直接在 Svelte 等声明式框架中使用 DOM API(例如 querySelector
)。如果您需要访问元素本身,通常 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
}