为什么我不能在这个 Svelte 应用程序的组件中保留与组件相关的操作?
Why can't I keep component-related actions within the component in this Svelte app?
出于学习目的,我正在使用 Svelte 开发一个小型用户应用程序(我是 Svelte 的新手)。
在App.Svelte中,我遍历一组用户:
<script>
const apiURL = "https://randomuser.me/api/";
import { onMount } from "svelte";
import Search from './Search.svelte';
import User from './User.svelte';
let users = [];
let stringToMatch = "";
$:filteredUsers = users;
onMount(() => {
getUsers();
});
const getUsers = () => {
let getFrom = "&results=20&inc=name,location,email,cell,picture";
fetch(`${apiURL}?${getFrom}`)
.then(res => res.json())
.then((data) => users = data.results);
};
let filterUsers = () => {
if (stringToMatch) {
filteredUsers = users.filter(user => {
return user.name.first.toLowerCase().includes(stringToMatch.toLowerCase()) ||
user.name.last.toLowerCase().includes(stringToMatch.toLowerCase()) ||
user.location.city.toLowerCase().includes(stringToMatch.toLowerCase());
});
} else filteredUsers = users;
};
</script>
<div class="container-fluid">
<div class="card bg-light mb-2 overflow-hidden">
<div class="card-header px-2 py-0 d-flex">
<h6 class="text-dark m-0 align-self-center">Members Area</h6>
</div>
<div class="card-body bg-white p-0">
<Search {filterUsers} bind:stringToMatch={stringToMatch} />
{#if filteredUsers.length > 0}
<table class="table users-table m-0">
<thead>
<tr>
<th class="text-right">#</th>
<th>Name</th>
<th>Lives in</th>
<th class="text-right">Actions</th>
</tr>
</thead>
<tbody>
{#each filteredUsers as user,index (user)}
<User {user} {index} on:Delete = {deleteUser(user)} />
{/each}
</tbody>
</table>
{:else}
<p class="text-center text-muted my-3">No members found</p>
{/if}
</div>
</div>
</div>
从上面的循环中可以看出,我显示了 User.svelte
组件中的每个用户。每个与用户相关的 action(例如删除用户)都在此组件中实时显示,这似乎合乎逻辑。所以,我在这里有:
const dispatch = createEventDispatcher();
const Delete = () => dispatch("deleteUser", user);
const deleteUser = (user) => {
let itemIdx = filteredUsers.findIndex(x => x == user);
filteredUsers.splice(itemIdx, 1);
filteredUsers = filteredUsers;
}
然而,我得到了这个 'deleteUser' is not defined
错误,如 REPL.
中所示
问题
- 我做错了什么?
- 如何将
deleteUser
方法保留在 User.svelte
内并成功使用它?
您正在 User
组件中定义 deleteUser
,但您试图在 App
中使用它,但它确实没有定义。所以这个错误在我看来并不奇怪。
您遇到的问题之一是您的删除函数作用于一个数组,该数组不是组件的一部分 (filteredUsers),所以即使您调用 deleteUser
直接在组件内部你会得到另一个 undefined 错误。
我在这里看到的是,从逻辑上讲,您希望将处理单个用户的所有逻辑都保留在 User
中,但这样做您会吸收处理整个用户的逻辑(数组),这是不一致的:作为数组的用户本身是 App
的一部分,为什么要将与数组相关的逻辑从它所属的位置中取出?
在我看来,删除一个用户不是item自身执行的功能,而是数组持有者完成的功能。因此,在您的情况下,您最好将 deleteUser
移动到 App
。
如果你这样做,用户组件将负责
- 显示一个个人用户
- 可能编辑个人用户
而应用程序将负责
- 显示列表 用户
- adding/removing 用户 list
出于学习目的,我正在使用 Svelte 开发一个小型用户应用程序(我是 Svelte 的新手)。
在App.Svelte中,我遍历一组用户:
<script>
const apiURL = "https://randomuser.me/api/";
import { onMount } from "svelte";
import Search from './Search.svelte';
import User from './User.svelte';
let users = [];
let stringToMatch = "";
$:filteredUsers = users;
onMount(() => {
getUsers();
});
const getUsers = () => {
let getFrom = "&results=20&inc=name,location,email,cell,picture";
fetch(`${apiURL}?${getFrom}`)
.then(res => res.json())
.then((data) => users = data.results);
};
let filterUsers = () => {
if (stringToMatch) {
filteredUsers = users.filter(user => {
return user.name.first.toLowerCase().includes(stringToMatch.toLowerCase()) ||
user.name.last.toLowerCase().includes(stringToMatch.toLowerCase()) ||
user.location.city.toLowerCase().includes(stringToMatch.toLowerCase());
});
} else filteredUsers = users;
};
</script>
<div class="container-fluid">
<div class="card bg-light mb-2 overflow-hidden">
<div class="card-header px-2 py-0 d-flex">
<h6 class="text-dark m-0 align-self-center">Members Area</h6>
</div>
<div class="card-body bg-white p-0">
<Search {filterUsers} bind:stringToMatch={stringToMatch} />
{#if filteredUsers.length > 0}
<table class="table users-table m-0">
<thead>
<tr>
<th class="text-right">#</th>
<th>Name</th>
<th>Lives in</th>
<th class="text-right">Actions</th>
</tr>
</thead>
<tbody>
{#each filteredUsers as user,index (user)}
<User {user} {index} on:Delete = {deleteUser(user)} />
{/each}
</tbody>
</table>
{:else}
<p class="text-center text-muted my-3">No members found</p>
{/if}
</div>
</div>
</div>
从上面的循环中可以看出,我显示了 User.svelte
组件中的每个用户。每个与用户相关的 action(例如删除用户)都在此组件中实时显示,这似乎合乎逻辑。所以,我在这里有:
const dispatch = createEventDispatcher();
const Delete = () => dispatch("deleteUser", user);
const deleteUser = (user) => {
let itemIdx = filteredUsers.findIndex(x => x == user);
filteredUsers.splice(itemIdx, 1);
filteredUsers = filteredUsers;
}
然而,我得到了这个 'deleteUser' is not defined
错误,如 REPL.
问题
- 我做错了什么?
- 如何将
deleteUser
方法保留在User.svelte
内并成功使用它?
您正在 User
组件中定义 deleteUser
,但您试图在 App
中使用它,但它确实没有定义。所以这个错误在我看来并不奇怪。
您遇到的问题之一是您的删除函数作用于一个数组,该数组不是组件的一部分 (filteredUsers),所以即使您调用 deleteUser
直接在组件内部你会得到另一个 undefined 错误。
我在这里看到的是,从逻辑上讲,您希望将处理单个用户的所有逻辑都保留在 User
中,但这样做您会吸收处理整个用户的逻辑(数组),这是不一致的:作为数组的用户本身是 App
的一部分,为什么要将与数组相关的逻辑从它所属的位置中取出?
在我看来,删除一个用户不是item自身执行的功能,而是数组持有者完成的功能。因此,在您的情况下,您最好将 deleteUser
移动到 App
。
如果你这样做,用户组件将负责
- 显示一个个人用户
- 可能编辑个人用户
而应用程序将负责
- 显示列表 用户
- adding/removing 用户 list