Route::resource 建立的 DELETE API 设定上只能删除一笔资料。
请求方法 | 路由 | 控制器函式 | 路由名称标签 |
---|---|---|---|
DELETE | /todos/{id} | destroy | todos.destroy |
不过像 Todo 这种清单显示的资料一笔笔删也太麻烦了,所以这边先实作批量删除的功能。
首先新增一个路由
## /routes/web.php
@@ -30,5 +30,6 @@ Route::get('/dashboard', [TodoController::class, 'index'])
Route::resource('todo', TodoController::class);
+Route::put('todos', [TodoController::class,'delete'])->name('todos.delete');
在 TodoController 新增一个 delete 方法
## /app/Http/Controllers/TodoController.php
@@ -96,4 +96,13 @@ class TodoController extends Controller
{
//
}
+
+
+ public function delete(Request $request )
+ {
+ $data = $request->all(); // 取得请求中的 body 资料
+ $todoIds = $data['ids'];
+
+ Todo::destroy($todoIds);
+ }
}
destroy 方法可以传入主键阵列删除对应的资料,像这边就是传入 todo 的 id 清单,整批删除对应 id 的资料。
destroy 也能删除单一 id 资料
Todo::destroy(1);
如果删除资料不是根据主键而是其他条件,也可以在搜寻资料後呼叫 delete() 方法删除。
// 搜寻 id 在 todoIds 阵列中的资料,批次删除
Todo::whereIn('id', $todoIds )->delete();
// 也可以分段写
$todoQuery = Todo::whereIn('id', $todoIds );
$todoQuery->delete();
帮清单加上勾选框
## /resources/js/Pages/Dashboard.js
@@ -10,6 +10,9 @@ import {
Grid,
IconButton,
Box,
+ ListItemIcon,
+ ListItemButton,
+ Checkbox,
} from "@mui/material";
import { Head, Link, useForm } from "@inertiajs/inertia-react";
import { Inertia } from "@inertiajs/inertia";
@@ -26,7 +29,7 @@ export default function Dashboard(props) {
);
const [todoList, setTodoList] = useState(
- todos.map((todo) => ({ ...todo, editing: false }))
+ todos.map((todo) => ({ ...todo, editing: false, checked: false }))
);
const handleChange = (event) => {
@@ -82,6 +85,15 @@ export default function Dashboard(props) {
}
);
};
+
+ const toggleCheck = (todoId) => {
+ const newList = todoList.map((todo) =>
+ todo.id === todoId ? { ...todo, checked: !todo.checked } : todo
+ );
+
+ setTodoList(newList);
+ };
+
return (
<Authenticated
auth={props.auth}
@@ -133,6 +145,7 @@ export default function Dashboard(props) {
<ListItem
button
key={item.id}
+ disablePadding
secondaryAction={
<IconButton
edge='end'
@@ -163,7 +176,21 @@ export default function Dashboard(props) {
}}
/>
) : (
- <ListItemText primary={item.name} />
+ <ListItemButton
+ role={undefined}
+ onClick={() => toggleCheck(item.id)}
+ dense>
+ <ListItemIcon>
+ <Checkbox
+ edge='start'
+ checked={item.checked}
+ // tabIndex={-1}
+ disableRipple
+ // inputProps={{ "aria-labelledby": labelId }}
+ />
+ </ListItemIcon>
+ <ListItemText primary={item.name} />
+ </ListItemButton>
)}
</ListItem>
))}
还需要一个发送删除请求的按钮,就设定成当有勾选的项目时 Add 按钮会变成删除按钮吧
## /resources/js/Pages/Dashboard.js
@@ -1,4 +1,4 @@
-import React, { useState } from "react";
+import React, { useState, useMemo } from "react";
import Authenticated from "@/Layouts/Authenticated";
import {
Container,
@@ -94,6 +94,15 @@ export default function Dashboard(props) {
setTodoList(newList);
};
+ const hasChecked = useMemo(
+ () => todoList.findIndex((todo) => todo.checked) >= 0,
+ [todoList]
+ );
+
+ const requestDelete = () => {
+ // 发送删除请求
+ };
+
return (
<Authenticated
auth={props.auth}
@@ -130,13 +139,23 @@ export default function Dashboard(props) {
variant='standard'
style={{ marginRight: 4 }}
/>
- <Button
- type='submit'
- variant='contained'
- color='primary'
- disabled={processing}>
- Add
- </Button>
+ {hasChecked ? (
+ <Button
+ variant='contained'
+ color='error'
+ disabled={processing}
+ onClick={requestDelete}>
+ Delete
+ </Button>
+ ) : (
+ <Button
+ type='submit'
+ variant='contained'
+ color='primary'
+ disabled={processing}>
+ Add
+ </Button>
+ )}
</Grid>
</form>
<Box sx={{ width: "100%", maxWidth: 360 }}>
加入删除请求,用勾选项目的 id 阵列传送删除请求,一样在请求结束後重新载入 todo 清单
@@ -100,7 +100,17 @@ export default function Dashboard(props) {
);
const requestDelete = () => {
- console.log("Delete");
+ Inertia.put(
+ route("todos.delete"),
+ {
+ ids: todoList.filter((todo) => todo.checked).map((todo) => todo.id),
+ },
+ {
+ onFinish: (visit) => {
+ Inertia.reload({ only: ["todos"] });
+ },
+ }
+ );
};
今天的内容为建立房间的场景以及离开房间Button。 ...
1. 前言: 之前想要实现在几公尺外遥控 mac book,於是就在虾皮上找到了这个蓝牙摇杆,虽然怀...
我们在上一次讲到用数理观点来观察反射行为的诸多细节,而这篇文则是要讲解斜向抛射。 不过因为斜向抛射的...
前言 JS 30 是由加拿大的全端工程师 Wes Bos 免费提供的 JavaScript 简单应用...
前言 觉得这个文章,花了太多时间在写但有些设定好像应该 更把他分的更清楚而不是一直只丢范例出来解释。...