英文:
SvelteKit Form actions and update UI
问题
我是初学者,正在尝试使用SvelteKit构建一个待办事项应用程序。这个问题关注的是我遇到的问题,同时也在询问数据获取和UI更新的逻辑是否正确。
我的表单如下:
<form
action="?/create"
method="POST"
class="flex flex-col gap-5 justify-center items-center w-2/3 mx-auto"
use:enhance
>
<div class="w-2/3">
<label class="block text-sm text-gray-500" for="todo"> Title </label>
<input
class="border border-gray-300 w-full rounded-md shadow-sm hover:border-gray-400 focus:outline-none focus:border-gray-500 transition duration-100 ease-linear p-1 text-gray-700"
type="text"
name="title"
bind:value={title}
/>
</div>
<div class="w-2/3">
<label class="block text-sm text-gray-500" for="todo">
Description
</label>
<textarea
rows="4"
class="w-full border border-gray-300 rounded-md shadow-sm hover:border-gray-400 focus:outline-none focus:border-gray-500 transition duration-100 ease-linear p-1 text-gray-700"
name="desc"
bind:value={desc}
/>
</div>
<div>
<button
class="bg-blue-500 text-white px-8 py-2 rounded-md font-semibold text-lg hover:bg-blue-600 transition duration-100 shadow-xl"
>
Create
</button>
</div>
</form>
在+page.server.js中,我这样捕获表单操作:
export const actions = {
create: async ({ cookies, request }) => {
const data = await request.formData();
if (data.get("title").length === 0) {
return fail(400, {
error: true,
message: "Title can't be empty",
});
}
if (data.get("desc").length === 0) {
return fail(400, {
error: true,
message: "Description can't be empty",
});
}
const todo = {
title: data.get("title"),
description: data.get("desc"),
};
try {
const newTodos = await createTodo(todo);
todosStore.set(newTodos);
} catch (err) {
return fail(422, {
description: "Something went wrong",
});
}
},
};
createTodo函数如下:
export const createTodo = async (todo) => {
try {
const todoRes = await db.collection("ToDo").insertOne({
todo,
});
const newTodos = await getTodos();
return newTodos;
} catch (err) {
console.log(err);
}
};
然后我在page.svelte文件中订阅了todosStore并渲染了待办事项列表:
import { todosStore } from "../stores/todoStore.js";
let todos = $todosStore;
<ToDoList {todos} />
虽然我向后端发送了POST请求,我的新待办事项已经正确添加到数据库,并且函数也正常工作,但我在UI上没有看到更改。
我的代码有什么问题?这是否是在SvelteKit应用程序中应用这种逻辑的正确方式?
谢谢。
英文:
I am a beginner with SvelteKit and trying to build a todo app. This question focuses on the following problem I have, but also asking if it's the correct logic to do data fetching and UI update.
My form is this:
<form
action="?/create"
method="POST"
class="flex flex-col gap-5 justify-center items-center w-2/3 mx-auto"
use:enhance
>
<div class="w-2/3">
<label class="block text-sm text-gray-500" for="todo"> Title </label>
<input
class="border border-gray-300 w-full rounded-md shadow-sm hover:border-gray-400 focus:outline-none focus:border-gray-500 transition duration-100 ease-linear p-1 text-gray-700"
type="text"
name="title"
bind:value={title}
/>
</div>
<div class="w-2/3">
<label class="block text-sm text-gray-500" for="todo">
Description
</label>
<textarea
rows="4"
class="w-full border border-gray-300 rounded-md shadow-sm hover:border-gray-400 focus:outline-none focus:border-gray-500 transition duration-100 ease-linear p-1 text-gray-700"
name="desc"
bind:value={desc}
/>
</div>
<div>
<button
class="bg-blue-500 text-white px-8 py-2 rounded-md font-semibold text-lg hover:bg-blue-600 transition duration-100 shadow-xl"
>
Create
</button>
</div>
</form>
On the +page.server.js I catch the form action like so:
export const actions = {
create: async ({ cookies, request }) => {
const data = await request.formData();
if (data.get("title").length === 0) {
return fail(400, {
error: true,
message: "Title can't be empty",
});
}
if (data.get("desc").length === 0) {
return fail(400, {
error: true,
message: "Description can't be empty",
});
}
const todo = {
title: data.get("title"),
description: data.get("desc"),
};
try {
const newTodos = await createTodo(todo);
todosStore.set(newTodos);
} catch (err) {
return fail(422, {
description: "Something went wrong",
});
}
},
};
The createTodo function is the following:
export const createTodo = async (todo) => {
try {
const todoRes = await db.collection("ToDo").insertOne({
todo,
});
const newTodos = await getTodos();
return newTodos;
} catch (err) {
console.log(err);
}
};
I then subscribe to the todosStore on my page.svelte file and render a list of todos like this:
import { todosStore } from "../stores/todoStore.js";
let todos = $todosStore;
<ToDoList {todos} />
While I do send the POST request to the backend and my new todo is correctly added to the database and the function also does its work, I do not see the change on my UI.
What is the problem with my code? Also is this the correct way to apply this kind of logic in SvelteKit apps?
Thank you.
答案1
得分: 3
不应在服务器上使用存储。
数据不会自动传输,服务器上的存储引用与客户端完全独立。
您的操作应返回 todo 对象,然后将其传递给+page.svelte
组件的form
属性。如果您需要以类似本例的方式对返回的数据进行操作,您可以向enhance
添加参数以拦截返回的数据,例如触发一个项目已添加事件或将项目添加到全局存储。
示例:
<form use:enhance={onSubmit}>
const onSubmit = () => {
return ({ result, update }) => {
if (result.type === "success") {
const todo = result.data;
console.log("新待办事项", todo);
}
else {
update();
}
}
}
另一种方法是使用数据加载。在表单提交时,页面的data
属性将自动重新加载,因此,如果您有一个从数据库中获取所有项目并将页面数据传递给列表组件的load
函数,它将自动更新。
英文:
You cannot/should not use stores on the server.
The data will not be magically transferred, any store reference on the server is a completely separate instance from the client.
Your action should return the todo-object, which will then be passed to the form
property of the +page.svelte
component. If you need to imperatively interact with the returned data as in this case, you can add a parameter to enhance
to intercept the return data and e.g. fire an event that an item has been added or add the item to a global store.
Example:
<form use:enhance={onSubmit}>
const onSubmit = () => {
return ({ result, update }) => {
if (result.type === "success") {
const todo = result.data;
console.log("New todo", todo);
}
else {
update();
}
}
}
An alternative to this would be using data loading. On form submission the data
property of the page will automatically reload, so if you have a load
function that gets all items from the DB and the page data is passed to the list component, it will update automatically.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论