Svelte 应用程序错误:未返回未完成的待办事项 [英] Svelte app bug: uncompleted todos are not returned

查看:30
本文介绍了Svelte 应用程序错误:未返回未完成的待办事项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on a small todo app with Svelte. I list 10 todos from jsonplaceholder.

我想统计completed属性等于false的todos:

I want to count the todos whose completed property is equal to 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);

正如在这个REPL中所见unsolvedTodos 数组为空.

As can be seen in this REPL, the unsolvedTodos array is empty.

我得到了未解决的待办事项列表及其长度,但我无法在标题组件中使用它.

I got the list of unsolved todos and its length, but I can not use it in the header component.

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 中所见,使用 {unsolvedTodos.length} 会抛出一个 unsolvedTodos is not defined 错误,尽管我导入了 ToDoList.

As visible in the REPL, using <span class="count">{unsolvedTodos.length}</span> throws an unsolvedTodos is not defined error, evan though I imported the ToDoList.

我的错误在哪里?

推荐答案

简单地将一个组件导入另一个组件不会暴露其属性.因此,您不能 import TodoList from './TodoList.svelte'; 并期望 unsolvedTodos 在 Header 中可用.您所拥有的只是组件 TodoList.从您的代码中,您似乎在尝试访问未定义变量 todosTodoItem 中犯了同样的错误.

Simply importing a component into another will not expose its properties. So you cannot do import TodoList from './TodoList.svelte'; and expect unsolvedTodos to be available in the Header. All you have available is the component TodoList. From your code, you seem to make the same mistake in TodoItem where you try to access the undefined variable todos.

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

The problem you are facing here is that you need to share data between two or more components that have no direct relation to each other (they are not parent and child). Sharing data between such components is usually solved in one of two ways:

通过父母

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

The first solution is to move the state or data to the parent. In your case that would mean that the actual list of todos and all logic regarding adding, removing, toggling, etc... is stored in App.svelte and the other components become mere representation components to which you pass this list.

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

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

<TodoList todos={todos} />

正如您在此处看到的,App 负责跟踪待办事项,而 List 组件只会显示它们.如果你想在列表中添加一个新项目,你可以在这里而不是在 TodoList 中做同样如果你改变一个项目的状态,你必须把它冒泡一直到 App.svelte 并且不会改变 TodoItem 中的状态,因为它只会显示当前状态.

As you see here, the App is responsible for keeping track of the todos, while the List component would only show them. If you want to add a new item to the list, you would do it here and not in TodoList Same if you change the state of an item, you have to bubble it all the way up to App.svelte and not change the state in TodoItem that one would be purely showing the current state.

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

This last part is a bit cumbersome so a better option might be to

使用商店

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

Using [stores][1] you can define one single point to keep your state and then import that state into the components that need it, for example the TodoList would be:

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

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

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

Similarly TodoItem could import this store and update the responding element in the list. (Best would be to use a custom store for this so all logic really now resides in the store object).

这篇关于Svelte 应用程序错误:未返回未完成的待办事项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆