如何在SvelteKit Actions中获取表单提交按钮的名称?
问题描述
我有一个包含两个提交按钮的表单:
<form method="POST" class="pt-10"> <div class="flex flex-row pt-10"> <button type="submit" name="save-and-exit" class="btn btn-primary btn-lg">{ mode == "new" ? "Save and Exit" : "Update and Exit" }</button> </div> <div class="flex flex-row pt-10"> <button type="submit" name="add-tracks" class="btn btn-primary btn-lg">{ "-> Tracks" }</button> </div> </form>
(为简化展示,省略了表单中的字段)
我的Action代码如下:
export const actions = { default: async ({ request, fetch }) => { // create API instance const recordAPI = new RecordAPI(fetch); // retrieve the data from the form const data = Object.fromEntries(await request.formData()); // validate data and create DTO const record = recordDTO(data); // if errors returned from building the DTO (validation errors) then return the object. if (record?.errors && !emptyObject(record.errors)) { return { "data": record.data, "errors": record.errors, }; } // save the data const response = await recordAPI.post(record); if (response.status == 200) { throw redirect(302, '/records') } return { data: record, "errors": response.errors, } }
我需要在Action函数中判断是哪个提交按钮触发了表单提交,因为不同按钮对应不同的业务流程。我想到的一种解决方案是修改表单,通过bind:this获取表单元素,手动添加按钮名称后调用formElement.requestSubmit(),但想知道是否有更优雅的方式直接在Action中实现?
解决方案
完全不需要修改表单或手动处理提交逻辑,HTML表单原生就支持在提交时携带触发按钮的信息——当用户点击某个带name属性的提交按钮时,该按钮的name会作为键出现在表单数据中(若未设置value,对应值为空字符串)。
直接在Action里通过formData判断即可,修改后的代码如下:
export const actions = { default: async ({ request, fetch }) => { const recordAPI = new RecordAPI(fetch); const formData = await request.formData(); // 判断触发提交的按钮 const isSaveAndExit = formData.has('save-and-exit'); const isAddTracks = formData.has('add-tracks'); // 转换为普通对象(按需使用) const data = Object.fromEntries(formData); const record = recordDTO(data); if (record?.errors && !emptyObject(record.errors)) { return { "data": record.data, "errors": record.errors, }; } const response = await recordAPI.post(record); if (response.status == 200) { // 根据不同按钮执行对应业务逻辑 if (isSaveAndExit) { throw redirect(302, '/records'); } else if (isAddTracks) { // 示例:跳转到添加曲目页面 throw redirect(302, `/records/${record.id}/tracks`); } } return { data: record, "errors": response.errors, } } }
核心要点
- 依托HTML原生表单行为,无需额外前端代码,点击带
name的提交按钮时,其name会自动被包含在formData中 - 使用
formData.has('按钮name')即可快速判断触发源 - 这种方式符合规范、代码简洁,无需维护额外的表单绑定逻辑
内容的提问来源于stack exchange,提问作者MrCujo
相关产品推荐
相关产品推荐

