Skip to main content

Một trang chỉ có một action duy nhất thì thực tế là khá hiếm. Hầu hết trường hợp, bạn sẽ cần có nhiều action trên một trang. Trong ứng dụng này, việc tạo một todo mới là không đủ — chúng ta muốn xóa chúng sau khi đã hoàn thành.

Bắt đầu bằng cách thay thế action default bằng các action có tên createdelete:

src/routes/+page.server.js
export const actions = {
	create: async ({ cookies, request }) => {
		const data = await request.formData();
		db.createTodo(cookies.get('userid'), data.get('description'));
	},

	delete: async ({ cookies, request }) => {
		const data = await request.formData();
		db.deleteTodo(cookies.get('userid'), data.get('id'));
	}
};

Action mặc định không thể cùng tồn tại cùng với các hành động có tên.

Phần tử

có một thuộc tính tùy chọn là action, tương tự như thuộc tính href của phần tử . Chúng ta hãy cập nhật form hiện tại để nó trỏ đến hành động create mới:

src/routes/+page.svelte
<form method="POST" action="?/create">
	<label>
		thêm todo:
		<input
			name="description"
			autocomplete="off"
		/>
	</label>
</form>

Thuộc tính action có thể là bất kỳ URL nào. Ví dụ nếu action create được thiết lập ở trang /todos, ta sẽ dùng /todos?/create. Vì action ở trang này, nên chúng ta có thể bỏ qua toàn bộ đường dẫn và chỉ cần thêm ký tự ? ở trước.

Tiếp theo, chúng ta muốn tạo một form cho mỗi todo, kèm theo một <input> ẩn duy nhất để xác định nó:

src/routes/+page.svelte
<ul class="todos">
	{#each data.todos as todo (todo.id)}
		<li>
			<form method="POST" action="?/delete">
				<input type="hidden" name="id" value={todo.id} />
				<span>{todo.description}</span>
				<button aria-label="Mark as complete"></button>
			</form>
		</li>
	{/each}
</ul>

Tiếp theo: Validation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<script>
	export let data;
</script>
 
<div class="centered">
	<h1>todos</h1>
 
	<form method="POST">
		<label>
			thêm todo:
			<input
				name="description"
				autocomplete="off"
			/>
		</label>
	</form>
 
	<ul class="todos">
		{#each data.todos as todo (todo.id)}
			<li>
				{todo.description}
			</li>
		{/each}
	</ul>
</div>
 
<style>
	.centered {
		max-width: 20em;
		margin: 0 auto;
	}
 
	label {
		width: 100%;
	}
 
	input {
		flex: 1;
	}
 
	span {
		flex: 1;
	}
 
	button {
		border: none;
		background: url(./remove.svg) no-repeat 50% 50%;
		background-size: 1rem 1rem;
		cursor: pointer;
		height: 100%;
		aspect-ratio: 1;
		opacity: 0.5;
		transition: opacity 0.2s;
	}
 
	button:hover {
		opacity: 1;
	}
 
	.saving {
		opacity: 0.5;
	}
</style>
 
initialising