简体   繁体   English

Svelte todo 应用程序错误:表单验证错误不显示

[英]Svelte todo app bug: form validation errors do not show up

I am working on a small ToDo application in Svelte for learning purposes (I'm new to Svelte).我正在 Svelte 中开发一个用于学习目的的小型 ToDo 应用程序(我是 Svelte 的新手)。

I got stuck trying to add validation errors to the New Todo form.我在尝试向New Todo表单添加验证错误时遇到了困难。

Inside the <script> tags I have在我的<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 = '';
}

In the view:在视图中:

{#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>

For a reason I have not been able to find, the error validation message does not appear and the console shows Uncaught (in promise): if_block0.p is not a function .由于我无法找到的原因,没有出现错误验证消息,并且控制台显示Uncaught (in promise): if_block0.p is not a function

See the REPL here .请参阅此处的 REPL。

Where is my mistake?我的错误在哪里?

You need to notify Svelte of the change to the errors array:您需要通知 Svelte 对errors数组的更改:

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

Svelte doesn't track objects mutations, only assignments (ie = ). Svelte 不跟踪对象突变,只跟踪分配(即= )。 But I guess you know it already since you already have similar code in your component.但我想你已经知道了,因为你的组件中已经有类似的代码。

That being said, I think the error you've encountered could be considered a bug in Svelte.话虽如此,我认为您遇到的错误可能被认为是 Svelte 中的错误。 But it's probably not impacting a useful use case -- ie mutating a reactive variable, but not wanting the change to be reflected by Svelte.但它可能不会影响一个有用的用例——即改变一个反应变量,但不希望 Svelte 反映变化。

Also, unrelated, but I would strongly recommend against using var keyword for variables, in any JS code written today, but especially in a Svelte component where it can make confusing whether you want it reactive ( let ) or nor ( const ).此外,不相关,但我强烈建议不要在今天编写的任何 JS 代码中使用var关键字作为变量,尤其是在 Svelte 组件中,如果你想要它是响应式的( let )还是 nor ( const ),它会让人感到困惑。

EDIT编辑

You should probably also rely on Svelte to access the value of your input field, instead of using document.querySelector .您可能还应该依靠 Svelte 来访问输入字段的值,而不是使用document.querySelector

Something like this:像这样的东西:

<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} />

You very rarely need to use DOM API (eg querySelector ) directly in declarative frameworks like Svelte.您很少需要在 Svelte 等声明性框架中直接使用 DOM API(例如querySelector )。 If you need access to an element itself, you are generally better served by bind:this or using an action in Svelte.如果您需要访问元素本身,通常最好使用bind:this或使用 Svelte 中的操作。

The problem is solved completely if I replace如果我更换,问题就完全解决了

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

with

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM