Svelte 应用程序错误:未返回未完成的待办事项

Svelte app bug: uncompleted todos are not returned

我正在使用 Svelte 开发一个小型待办事项应用程序。我从 jsonplaceholder 中列出了 10 个待办事项。

我想统计 completed 属性 等于 false:

的待办事项
const apiURL = "https://jsonplaceholder.typicode.com/todos";
const limit = 10;
import { onMount } from "svelte";
import TodoItem from './TodoItem.svelte';
let todos = [];
let unsolvedTodos = [];

onMount(() => {
    getTodos();
});

const getTodos = () => {
    fetch(`${apiURL}?&_limit=${limit}`)
    .then(res => res.json())
    .then((data) => todos = data);
}

const getUnsolvedTodos = () => {
    unsolvedTodos = todos.filter(todo => {
        return todo.completed === false;
    })
}

$:console.log(unsolvedTodos);

this REPL中可以看出,unsolvedTodos数组是空的。


编辑

我得到了待办事项列表及其长度,但我不能在header组件中使用它.

const getTodos = () => {
    fetch(`${apiURL}?&_limit=${limit}`)
    .then(res => res.json())
    .then((data) => todos = data)
    .then(getUnsolvedTodos);
}

const getUnsolvedTodos = () => {
    unsolvedTodos = todos.filter(todo => {
        return todo.completed === false;
    })
}

$:console.log(unsolvedTodos.length); 

在 REPL 中可见,使用 <span class="count">{unsolvedTodos.length}</span> 会引发 unsolvedTodos is not defined 错误,尽管我导入了 ToDoList。

我的错误在哪里?

不要使用函数来计算,而是使用内联的过滤器代码和前缀 $ 使其具有反应性

$: unsolvedTodos = todos.filter(todo => { return todo.completed === 错误; });

并在模板中使用这个值

简单地将一个组件导入另一个组件不会暴露其属性。因此,您不能执行 import TodoList from './TodoList.svelte'; 并期望 unsolvedTodos 在页眉中可用。您只有 组件 TodoList。从你的代码来看,你似乎在 TodoItem 中犯了同样的错误,你试图访问未定义的变量 todos.

您在这里面临的问题是您需要在两个或多个彼此没有直接关系(它们不是父子)的组件之间共享数据。在这些组件之间共享数据通常通过以下两种方式之一解决:

通过父

第一个解决方案是将状态或数据移动到父级。在你的情况下,这意味着实际的待办事项列表和所有关于添加、删除、切换等的逻辑……存储在 App.svelte 中,而其他组件仅仅是 表示组件 您将此列表传递给它。

<script>
  import TodoList from './TodoList.svelte';

  let todos = []
  // Here comes logic for fetching the list and changing the state
</script>

<TodoList todos={todos} />

正如您在此处看到的,应用程序负责跟踪待办事项,而列表组件只会显示它们。如果你想向列表中添加一个新项目,你可以在这里而不是在TodoList中添加,如果你改变一个项目的状态也是如此,你必须将它一直冒泡到 App.svelte 而不是改变 TodoItem 中的状态当前状态。

最后一部分有点麻烦,所以更好的选择可能是

使用商店

使用 [stores][1],您可以定义一个点来保存您的状态,然后将该状态导入到需要它的组件中,例如 TodoList 将是:

<script>
  import { todos } from './store.js';
  import TodoItem from './TodoItem.svelte';
</script>

{#each $todos as todo}
  <TodoItem todo={todo} />
{/each}

类似地,TodoItem 可以导入该商店并更新列表中的响应元素。 (最好为此使用自定义存储,这样所有逻辑现在都真正驻留在存储对象中)。