【问题标题】:Svelte todo app bug: title property returns undefinedSvelte todo 应用程序错误:标题属性返回未定义
【发布时间】:2020-07-01 04:22:12
【问题描述】:

我正在 Svelte 中开发一个用于学习目的的小型 ToDo 应用程序(我是 Svelte 新手)。

在我看来:

<div class="input-group p-2" id="editForm">
  <input type="text" class="form-control" id="old_todo" value={currentToDo.title} placeholder="Edit Todo">
  <div class="input-group-append">
    <button on:click="{addTodo}" class="btn btn-sm btn-success">Save</button>
  </div>
</div>

//More code

{#each todos as t, index}   
<tr>
  <td>{index + 1}</td>
  <td class="{t.completed == true ? 'completed' : ''}">{t.title}</td>
  <td class="text-center"><input type="checkbox" on:change={completeTodo(t.id)}></td>
  <td class="text-right">
    <div class="btn-group">
      <button on:click="{editTodo(t.id)}" class="btn btn-sm btn-primary">Edit</button>
      <button on:click="{deleteTodo(t.id)}" class="btn btn-sm btn-danger">Delete</button>
    </div>
  </td>
</tr>
{/each}

我认为与此处相关的脚本部分:

<script>
    import {onMount} from "svelte";

    const apiURL = "https://jsonplaceholder.typicode.com/todos?_start=1&_limit=20";

    let todos = [];

    onMount(async function() {
        const response = await fetch(apiURL);
        todos = await response.json();
        todos.reverse();
    });

    var currentToDo = {};

    function editTodo(tid) {
        let itemIdx = todos.findIndex(x => x.id == tid);
        let currentToDo = todos[itemIdx];
    }

<script>

查看 REPL here

问题在于文本字段&lt;input type="text" class="form-control" id="old_todo" value={currentToDo.title} placeholder="Edit Todo"&gt; 显示undefined 而不是当前(需要编辑)的待办事项标题。

我的错误在哪里?

【问题讨论】:

    标签: javascript svelte svelte-3 svelte-2


    【解决方案1】:

    嗯,currentToDo.title 真的是undefined...

    如果你想避免这种显示,你可以改为currentToDo.title || ''

    <input type="text" class="form-control" id="old_todo" value={currentToDo.title || ''} placeholder="Edit Todo">
    

    另外,为了让你编辑按钮工作......

    改变这个:

    <button on:click="{editTodo(t.id)}" class="btn btn-sm btn-primary">Edit</button>
    

    到这里:

    <button on:click="{() => editTodo(t.id)}" class="btn btn-sm btn-primary">Edit</button>
    

    on:click="{editTodo(t.id)} 变为 on:click="{() =&gt; editTodo(t.id)},否则您的 editTodo 函数会在每次渲染时调用一次,但不会在实际单击按钮时调用(在 Svelte 中,您传递的是函数引用,而不是函数 body 比如普通的 HTML onclick)。

    另外,在您的 editTodo 函数中:

        function editTodo(tid){
            let itemIdx = todos.findIndex(x => x.id == tid);
            let currentToDo = todos[itemIdx];
        } 
    

    您需要删除此 let 以使用根范围 currentToDo,而不是本地范围的变量:

        function editTodo(tid){
            let itemIdx = todos.findIndex(x => x.id == tid);
            currentToDo = todos[itemIdx];
        } 
    

    然后你可以点击一个编辑按钮,标题会按预期显示在输入字段中!

    【讨论】:

    • 当然:let currentToDo = todos[itemIdx]; 是问题所在。傻我。不过,您能否解释一下为什么需要替换 {editTodo(t.id)} wixth () =&gt; editTodo(t.id)。谢谢!
    • 在 Svelte 中,您需要将函数传递给事件处理程序。也就是说,卷曲的内容必须是一个函数。 {editTodo} 将传递函数editTodo,但您需要它使用本地参数t.id,因此您将其设为使用参数editTodo 调用editTodo 的函数:{() =&gt; editTodo(t.id)}{editTodo(t.id)} 是调用editTodo(t.id) 的结果;每次评估(更新)模板时都会调用它,而不是触发点击事件时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多