You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte/SuperForm复选框问题:获取值而非布尔值及分组绑定异常

使用SuperForm(搭配formFieldProxy)处理复选框的问题
  • 无法获取复选框的value属性值,只能得到代表选中状态的布尔值(原生HTML复选框在选中时会发送对应的value值);
  • 尝试使用bind:group绑定后,虽能获取复选框的value值,但所有值均以数组形式存储,不符合预期结构。

预订Zod Schema

const ReservationObject = z.object({
    id: z.string().uuid(),
    reservation_id: z.string(),
    denomination: z.string(),
    price: z.coerce.number(),
    options: z.array(
        z.object({
            id: z.string().uuid(),
            optionDenomination: z.string(),
            price: z.coerce.number()
        })
    ),
    total: z.number().optional(),
    isBooked: z.boolean()
});

const ReservationsObject = z.object({
    reservation_id: z.string(),
    isSuspended: z.boolean(),
    booking: z.array(ReservationObject)
});

表单值对应的Zod Schema

export const BuyingReservation = z.object({
    buying: z.array(
        z.object({
            buyReservation: z.string().uuid(),
            buyReservationOption: z.array(z.string().uuid())
        })
    )
});

SuperForm实例

const defaultBuyingEntry = [{ buyReservation: '', buyReservationOption: [] }];
const buying: BuyingReservation = { buying: defaultBuyingEntry };
const superform = superForm(buying, {
    dataType: 'json',
    resetForm: false,
    invalidateAll: false
});
const { form, submitting, enhance } = superform;

表单代码

<form method="POST" use:enhance action="/" class={styles['form']}>
    {#each booking.booking as item, index}
        <div class={styles['booking__row']}>
            <p class={styles['booking__row-denomination']}>
                {item.denomination} : <span>{item.price}€</span>
                <Input
                    {superform}
                    id={`${index}-buyReservation`}
                    field="buying[{index}].buyReservation"
                    type="checkbox"
                    label={'Réserver'}
                    value={item.id}
                    grouped={true}
                />
            </p>
            <div class={styles['booking__row-options']}>
                {#each item.options as option, optionIndex}
                    <div class={styles['booking__row-option']}>
                        <p class={styles['booking__row-options-denomination']}>
                            {option.optionDenomination} : <span>{option.price}€</span>
                        </p>
                        <Input
                            {superform}
                            id={`${index}-${optionIndex}-buyReservationOption`}
                            field="buying[{index}].buyReservationOption[{optionIndex}]"
                            type="checkbox"
                            label={'Ajouter'}
                            value={option.id}
                            grouped={true}
                        />
                    </div>
                {/each}
            </div>
        </div>
    {/each}
    <input
        type="submit"
        class={styles['form__field-static']}
        value="Reserver et payer"
        disabled={$submitting}
    />
</form>

可复用Input组件

let { label, className, field, superform, grouped, ...others }: Props = $props();
const { value, errors, constraints } =
    !!field && !!superform ? formFieldProxy(superform, field) : {};

<input
    {...others}
    name={field}
    data-invalid={$errors}
    aria-invalid={$errors ? 'true' : undefined}
    class={[styles['input'], className].join(' ')}
    {...$constraints}
    type="checkbox"
    bind:group={$value} // or bind:checked={$value}
/>

输出结果

使用bind:checked时:

{
    "buying": [
        {
            "buyReservation": true,
            "buyReservationOption": [
                true,
                false
            ]
        }
    ]
}

使用bind:group时:

{
    "buying": [
        {
            "buyReservation": [
                "61ee077d-9db9-4286-bd57-25d5ab0fe27e"
            ],
            "buyReservationOption": [
                [
                    "6b2fe441-96eb-46fe-aa2b-fe78319d27fc"
                ],
                [
                    "0fa3b2ab-e2bc-4407-8827-7de6a8f7fb06"
                ]
            ]
        }
    ]
}

内容的提问来源于stack exchange,提问作者Georgio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:50:17