接下來的步驟將把 todo 表單中的資料取出展示在 Dashboard 上。
首先看到 TodoController 中的 index 函式
// app\Http\Controllers\TodoController.php
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$todos = Todo::get(); //加入這行
}
get() 方法會將 Model 對應的表單中的所有資料取出。
接著就要將讀取到的 $todos 資料回傳給前端,如果是 API 的話就是將資料回傳
// app\Http\Controllers\TodoController.php
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$todos = Todo::get();
return $todos;
}
不過因為這邊想將資料顯示在 Dashboard 上,所以要回傳帶有 $todos 資料的 Dashboard 畫面
// app\Http\Controllers\TodoController.php
public function index()
{
$todos = Todo::get();
return inertia('Dashboard', [
'todos' => $todos,
]);
}
這樣 Dashboard 就能將 todos 作為 prop 傳入 Dashboard,再顯示出來
// resources\js\Pages\Dashboard.js
import { List , ListItem , ListItemText } from "@material-ui/core";
export default function Dashboard(props) {
const { todos } = props; // 取出 todos
// ...
return (
<Authenticated
auth={props.auth}
errors={props.errors}
header={
<h2 className="font-semibold text-xl text-gray-800 leading-tight">
Dashboard
</h2>
}
>
//...
<Container>
<form onSubmit={submit}>
//...
</form>
// 顯示 todos 列表
<List>
{todos.map((item) => (
<ListItem button>
<ListItemText primary={item.name} />
</ListItem>
))}
</List>
</Container>
</Authenticated>
);
}
接著將 /dashboard 路由的 Controller 替換成 TodoController
Route::get('/dashboard', [TodoController::class, 'index'])
->middleware(['auth', 'verified'])->name('dashboard');
這樣當進入 Dashboard 畫面時就能看到簡易的 todo 列表了
雖然有 todo 清單了不過目前還是靜態的資料,只會顯示呼叫當下取得的 todo 資料,每當新增 todo 後還得重新整理畫面才能看到新增的資料。
這時候就要應用 inertia.js 的局部更新資料功能了,
Inertia.reload({ only: ["todos"] });
Inertia.reload 會重新呼叫目前頁面的 url,而用 only 可以指定這次的讀取只要更新哪部分的資料。
像這裡指定 todos 那就只會更新這個 prop
// app\Http\Controllers\TodoController.php
public function index()
{
$todos = Todo::get();
return inertia('Dashboard', [
'todos' => $todos, // 對應這裡的鍵值
]);
}
所以每當我們新建好 todo 後就呼叫 Inertia.reload
// resources\js\Pages\Dashboard.js
export default function Dashboard(props) {
// ...
const submit = (e) => {
e.preventDefault();
transform((data) => ({
name: data.todo,
}));
post("/todo", {
// 新增資料結束後重載 todos
onFinish: (visit) => {
Inertia.reload({ only: ["todos"] });
reset(); //另外順便清空輸入框
},
});
};
//...
}
這樣在新增資料後就能馬上看到新增的 todo 了。
前面是利用 get() 方法將所有資料讀出來,不過通常我們可不這麼做,而是有條件的讀取出需要的資料。
Eloquent 讀取資料的函式都是沿用了 Laravel 原生的 Query Builder ,這邊列舉幾個常用的用法
沒錯又是 get ,get 的用法是將"目前條件"下的所有資料取出,前面直接在 Model 下使用 get 所以會將該 Model 對應的所有資料讀取出來。
Todo::get() // 讀取模型的所有資料
如果有加上其他的篩選條件,就會將符合該條件的所有資料取出
Todo::where('created_at', "<=", now()->subMonth())->get(); // 讀取早於一個月前建立的資料
基本的搜尋條件函式,是最常用也最多變的一環
基礎用法 where( 欄位 , 比較條件 , 目標值 ) ,比較欄位的值與目標值,符合條件的資料用 get 取出
Todo::where('created_at', "<=", now()->subMonth())->get();
通常都用用來比大小或相不相等
where('votes', '>', 100) //大於
where('votes', '>=', 100) //大於等於
where('votes', '<>', 100) //不等於
where('votes', '=', 100) //等於
where('votes', 100) // 等於的簡略寫法
也可以用資料庫支援的表達式
where('name', 'like', 'T%')
可以串接多個 where ,取交集
// 取年齡小於 60 且大於 35 的使用者
$users = User::where('age', '<', 60)
->where('age', '>', 35)
->get();
取聯集則是使用 orWhere
// 取年齡大於 35 或者名子為 John 的使用者
$users = User::where('age', '>', 35)
->orWhere('name', 'John')
->get();
可以一次篩選多個條件,取交集
$users = User::where([
['status', '=', '1'],
['subscribed', '<>', '1'],
])->get();
除了基本 where 還有其他衍伸的 where 函式
// 取介於範圍內/外的值
whereBetween('votes', [1, 100])
orWhereBetween('votes', [1, 100])
whereNotBetween('votes', [1, 100])
orWhereNotBetween('votes', [1, 100])
// 取包含 / 不包含在陣列中的值
whereIn('id', [1, 2, 3])
orWhereIn('id', [1, 2, 3])
whereNotIn('id', [1, 2, 3])
orWhereNotIn('id', [1, 2, 3])
// 取欄位是 / 不是 null 的資料
whereNull('deleted_at')
orWhereNull('deleted_at')
whereNotNull('deleted_at')
orWhereNotNull('deleted_at')
// 比較時間
whereDate('created_at', '2016-12-31')
whereDate('created_at', '<' , '2016-12-31')
whereMonth('created_at', '12')
whereDay('created_at', '31')
whereYear('created_at', '2016')
whereTime('created_at', '11:20:45')
//比較兩個欄位之間的值
whereColumn('first_name', 'last_name')
whereColumn('updated_at', '>', 'created_at')
可以將條件作為子集合組合出想要的搜尋條件
//名子為 John 且 votes 大於 100 或者 title 為 Admin
$users = User::where('name', '=', 'John')
->where(function ($query) {
$query->where('votes', '>', 100)
->orWhere('title', '=', 'Admin');
})
->get();
可以用 order 在讀取資料的同時將資料排序
$users = User::orderBy('name', 'desc')
->get();
asc = 升序
desc = 降序
可以串接多個 order ,會依序用條件排列
$users = User::orderBy('name', 'desc')
->orderBy('email', 'asc')
->get();
first 會取得當下條件排序第一位的資料
$flight = Flight::where('active', 1)->first();
如果沒有符合條件的資料,first 只會回傳 null,不會報錯。
如果想要在沒找到對應的資料時報錯的話,可以用 firstOrFail()
$flight = Flight::where('active', 1)->firstOrFail();
當拋出的 ModelNotFoundException 未被攔截的話, Laravel 會回傳 404 回應,包含對應的錯誤訊息。
find 會搜尋主鍵值找出一筆資料,通常都是用 id 當主鍵值來搜尋
$flight = Flight::find(1); // 尋找 id 為 1 的資料