Sveltekit从表单操作更新反应变量



因此,我正在使用Svltekit和Supadase开发一个简单的crud应用程序。我试图通过在用户选择排序选项时使用add.order()函数获取表来实现这个排序功能。我的问题是,我想在使用新的排序选项执行表单操作后更新smoothes变量。现在我只是像在加载函数中那样返回奶昔,但这似乎不对。那么,我该如何使用表单操作中的新数据来更新smothies和dom(而不是重新加载页面,因为它只会被默认的加载函数覆盖)。

我是斯维尔特基特和苏巴斯的新手,所以非常感谢你的帮助!

+page.svelte

<script>
import { enhance } from '$app/forms';
export let data;
$: ({ smoothies } = data);
const tabs = (e) => {
e.target.classList.add('tab-active');
const siblings = e.target.parentNode.children;
for (let i = 0; i < siblings.length; i++) {
if (siblings[i] !== e.target) {
siblings[i].classList.remove('tab-active');
}
}
};
const handleSubmit = ({ form, data, action, cancel, submitter }) => {
return async ({ result, update }) => {};
};
</script>
<div class="flex flex-col items-center mx-auto gap-8">
<a role="button" href="/create" class="btn btn-success mt-8">Create Smoothie</a>
<form action="?/sortSmoothies" method="POST" use:enhance={handleSubmit}>
<div class="tabs tabs-boxed">
<button
type="submit"
name="created_at"
value="true"
class="tab tab-active"
on:click={(e) => tabs(e)}>Created</button
>
<button type="submit" name="title" value="true" class="tab" on:click={(e) => tabs(e)}
>Title</button
>
<button type="submit" name="rating" value="true" class="tab" on:click={(e) => tabs(e)}
>Rating</button
>
</div>
</form>
<div class="grid 2xl:grid-cols-4 xl:grid-cols-3 lg:grid-cols-2 gap-6 mt-4">
{#each smoothies as smoothie}
<div class="card w-96 bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title">{smoothie.title}</h2>
<p>{smoothie.method}</p>
<div class="rating absolute -right-5 -top-5">
<div
class="mask mask-star-2 bg-orange-400 w-12 h-12 flex items-center justify-center font-bold"
>
{smoothie.rating}
</div>
</div>
<div class="card-actions justify-end">
<a role="button" href="/{smoothie.id}" class="btn btn-warning btn-sm">Edit</a>
<form action="?/deleteSmoothie" method="POST">
<input type="hidden" name="smoothie" value={JSON.stringify(smoothie)} />
<button type="submit" class="btn btn-error btn-sm">Remove</button>
</form>
</div>
</div>
</div>
{/each}
</div>
</div>

+page.server.js

import { supabase } from '$lib/supabaseClient';
import { fail } from '@sveltejs/kit';
const fetchSmoothies = async (orderBy) => {
const { data, error } = await supabase
.from('smoothies')
.select()
.order(orderBy, { ascending: false });
if (error) {
throw new Error('Could not fetch smoothies');
}
return data ?? [];
};
export const load = async () => {
console.log('load');
const data = await fetchSmoothies('created_at');
return {
smoothies: data ?? []
};
};
export const actions = {
deleteSmoothie: async ({ request }) => {
let { smoothie } = Object.fromEntries(await request.formData());
smoothie = JSON.parse(smoothie);
try {
await supabase.from('smoothies').delete().eq('id', smoothie.id);
} catch (err) {
console.error(err);
return fail(500, { message: 'Could not delete smoothie' });
}
},
sortSmoothies: async ({ request }) => {
console.log('action');
const formData = Object.fromEntries(await request.formData());
let orderBy;
for (const prop in formData) {
if (formData[prop] === 'true') {
orderBy = prop;
break;
}
}
const data = await fetchSmoothies(orderBy);
console.log(data);
return {
smoothies: data ?? []
};
}
};

您通常不应该从表单操作返回页面数据。当使用enhance操作时,成功的操作将自动使页面数据无效,从而导致load再次运行,从而更新您的列表。

尽管在这种情况下,您可能希望将排序变量转换为查询参数,这样load函数就可以访问它并以正确的顺序返回列表。您也不需要操作,而是使用goto用新参数更新URL。

简化示例:

function sort(e) {
const url = new URL($page.url);
url.searchParams.set('sort', e.currentTarget.value);
goto(url.href, { replaceState: true });
}
<select on:change={sort}>
<option value="asc">Ascending</option>
<option value="desc">Descending</option>
</select>
// +page.server.js
export const load = e => {
const sort = e.url.searchParams.get('sort');
// ...
};

当然,您可以使用多个参数,使用表单的submit事件来触发排序等。

最新更新