【问题标题】:Svelte todo app bug: form validation errors do not show upSvelte todo 应用程序错误:表单验证错误不显示
【发布时间】:2020-07-01 06:40:31
【问题描述】:

我正在 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

我的错误在哪里?

【问题讨论】:

    标签: javascript svelte svelte-3


    【解决方案1】:

    您需要通知 Svelte errors 数组的更改:

    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 中的操作通常会更好地为您服务。

    【讨论】:

    • 好收获。我在回答中添加了一些更一般的提示。
    【解决方案2】:

    如果我更换,问题就完全解决了

    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
    }
    

    【讨论】:

      猜你喜欢
      • 2018-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多