Svelte todo 应用程序错误:标题 属性 returns 未定义

Svelte todo app bug: title property returns undefined

出于学习目的,我正在使用 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

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

我的错误在哪里?

嗯,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="{() => 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];
    } 

然后您可以单击“编辑”按钮,标题将按预期显示在输入字段中!