我将 HTML 分成两个文件,
+page.svelte
和 Role.svelte
。这样它更干净、更易于维护,因为我将来会在 +page.svelte
中添加更多精简文件。 Role.svelte
包含表格。
我读过,因为
form
仅传递给 +page.svelte
而不是传递给任何组件,所以我应该在 let form: ActionData
上单独使用 Role.svelte
,而不是在 $page.form
中使用 Role.svelte
。我遇到的一个问题是 $page.form
没有类型安全和类型推断,与 ActionData
不同。如何在不牺牲文件组织的情况下使 $page.form
具有与 let form: ActionData
相同的推论?
(这是代码):
Role.svelte
<script lang="ts">
import { enhance } from "$app/forms";
import { page } from "$app/stores";
import type { ActionData } from "./$types";
let form: ActionData = $page.form // tried, returned undefined
form = form // did not change anything
let userRoles = ["admin", "student"];
</script>
<form method="post" action="?/role" use:enhance>
<!-- did not work, had to use $page.form which again has no typing -->
{#if form?.noSelectedRole}
<p>{form?.error}</p>
{/if}
<p>You are a/an...</p>
{#each userRoles as userRole}
<input type="radio" value={userRole} name="role" />
<label for={userRole}>{userRole}</label>
<br />
{/each}
<slot />
<!-- For when the school can't be found -->
<p>What school are you a part of? Type its DepEd school ID.</p>
<input type="text" name="schoolId" placeholder="School" />
<br />
<button type="submit">Check</button>
</form>
+page.svelte
<script lang="ts">
import { page } from "$app/stores";
import type { ActionData } from "./$types";
import Role from "./Role.svelte";
let form: ActionData = $page.form // did not work
</script>
<Role>
<p>
<!-- undefined, had to use $page.form but again, no typing :( -->
{console.log(form?.noSelectedRole)}
{#if form?.noSelectedRole}
Select a role please.
{/if}
</p>
</Role>
+page.server.ts
import type { Actions } from "./$types";
import { fail, redirect } from '@sveltejs/kit';
export const actions = {
role: async ({ request }) => {
const formData = await request.formData()
const userRole = formData.get("role") as string
const schoolId = formData.get("schoolId") as string
console.log(`role: ${userRole}`)
console.log(`school id: ${schoolId}`)
if (typeof userRole !== "string" ||
userRole == null) {
console.log("no user role selected")
return fail(400, {
noSelectedRole: true,
error: "Please select a role.",
data: {...{userRole, schoolId}}
})
}
}
} satisfies Actions;
您的方向是正确的,但您的代码中存在一些细微的错误。
// <Role.svelte>
import type { ActionData } from "./$types";
let form: ActionData = $page.form
第一次创建组件时,
form
是undefined
,因为还没有表单数据。提交表单后 $page.form
发生更改,但您的 form
变量不会更新,因为 SvelteKit 不会重新创建您的 Role
组件,它会重用它。
要解决此问题,您需要使
form
变量具有反应性:
// <Role.svelte>
import type { ActionData } from "./$types";
$: form = $page.form as ActionData
您的代码还有另一个问题,这次是在内部
+page.svelte
:
// <+page.svelte>
import type { ActionData } from "./$types";
let form: ActionData = $page.form;
有两件事:你不需要赋值,并且你需要导出变量。应该是这样的:
// <+page.svelte>
import type { ActionData } from "./$types";
export let form: ActionData;