Skip to content

Commit 97ffbce

Browse files
authored
Dịch phần 1-6: Bindings (sveltevietnam#78)
1 parent 2afdea2 commit 97ffbce

File tree

16 files changed

+72
-79
lines changed

16 files changed

+72
-79
lines changed
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
---
2-
title: Text inputs
2+
title: Input văn bản
33
---
44

5-
As a general rule, data flow in Svelte is _top down_ — a parent component can set props on a child component, and a component can set attributes on an element, but not the other way around.
5+
Có một luật chung là dòng dữ liệu trong Svelte chạy _từ trên xuống_component cha có thể đặt thuộc tính vào component con, và một component có thể đặt thuộc tính vào một phần tử, nhưng ngược lại thì không.
66

7-
Sometimes it's useful to break that rule. Take the case of the `<input>` element in this component — we _could_ add an `on:input` event handler that sets the value of `name` to `event.target.value`, but it's a bit... boilerplatey. It gets even worse with other form elements, as we'll see.
7+
Đôi khi phá luật sẽ có ích hơn. Trong trường hợp của phần tử `<input>` trong component này — ta _có thể_ thêm một hàm xử lý sự kiện `on:input` để thay đổi giá trị của `name` thành `event.target.value`, nhưng nó nhìn có vẻ... dài dòng. Ta sẽ thấy điều này sẽ trở nên tệ hơn cho những phần tử khác trong form.
88

9-
Instead, we can use the `bind:value` directive:
9+
Thay vào đó, ta có thể dùng chỉ thị `bind:value`:
1010

1111
```svelte
1212
/// file: App.svelte
1313
<input +++bind:+++value={name}>
1414
```
1515

16-
This means that not only will changes to the value of `name` update the input value, but changes to the input value will update `name`.
16+
Điều này có nghĩa là khi thay đổi giá trị của `name` sẽ làm thay đổi giá trị của ô nhập, mà thay đổi giá trị trong ô nhập cũng sẽ cập nhật `name`.

content/tutorial/01-svelte/06-bindings/02-numeric-inputs/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
2-
title: Numeric inputs
2+
title: Input số
33
---
44

5-
In the DOM, everything is a string. That's unhelpful when you're dealing with numeric inputs `type="number"` and `type="range"`as it means you have to remember to coerce `input.value` before using it.
5+
Trong DOM, mọi thứ sẽ là dải kí tự. Điều này sẽ không giúp gì cho bạn khi bạn phải làm việc với những ô nhập số `type="number"` `type="range"`tức là bạn phải nhớ chuyển kiểu cho giá trị của `input.value` trước khi sử dụng nó.
66

7-
With `bind:value`, Svelte takes care of it for you:
7+
Với `bind:value`, Svelte sẽ giúp bạn làm điều này:
88

99
```svelte
1010
/// file: App.svelte

content/tutorial/01-svelte/06-bindings/03-checkbox-inputs/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
2-
title: Checkbox inputs
2+
title: Input đánh dấu
33
---
44

5-
Checkboxes are used for toggling between states. Instead of binding to `input.value`, we bind to `input.checked`:
5+
Các ô đánh dấu được sử dụng cho việc bật tắt các trạng thái. Thay vì bind nó vào `input.value`, ta bind nó với `input.checked`:
66

77
```svelte
88
/// file: App.svelte

content/tutorial/01-svelte/06-bindings/03-checkbox-inputs/app-a/src/lib/App.svelte

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@
44

55
<label>
66
<input type="checkbox" checked={yes} />
7-
Yes! Send me regular email spam
7+
Vâng! Gửi tôi email spam thường xuyên
88
</label>
99

1010
{#if yes}
1111
<p>
12-
Thank you. We will bombard your inbox and sell
13-
your personal details.
12+
Cảm ơn! Chúng tôi sẽ gửi hàng tá email cho bạn và bán thông tin cá nhân của bạn.
1413
</p>
1514
{:else}
1615
<p>
17-
You must opt in to continue. If you're not
18-
paying, you're the product.
16+
Bạn phải tham gia để tiếp tục. Nếu bạn không trả tiền, thì bạn là sản phẩm.
1917
</p>
2018
{/if}
2119

content/tutorial/01-svelte/06-bindings/03-checkbox-inputs/app-b/src/lib/App.svelte

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@
44

55
<label>
66
<input type="checkbox" bind:checked={yes} />
7-
Yes! Send me regular email spam
7+
Vâng! Gửi tôi email spam thường xuyên
88
</label>
99

1010
{#if yes}
1111
<p>
12-
Thank you. We will bombard your inbox and sell
13-
your personal details.
12+
Cảm ơn! Chúng tôi sẽ gửi hàng tá email cho bạn và bán thông tin cá nhân của bạn.
1413
</p>
1514
{:else}
1615
<p>
17-
You must opt in to continue. If you're not
18-
paying, you're the product.
16+
Bạn phải tham gia để tiếp tục. Nếu bạn không trả tiền, thì bạn là sản phẩm.
1917
</p>
2018
{/if}
2119

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
2-
title: Select bindings
2+
title: Bind select
33
---
44

5-
We can also use `bind:value` with `<select>` elements:
5+
Ta cũng có thể dùng `bind:value` cho phần tử `<select>`:
66

77
```svelte
88
/// file: App.svelte
@@ -12,6 +12,6 @@ We can also use `bind:value` with `<select>` elements:
1212
>
1313
```
1414

15-
Note that the `<option>` values are objects rather than strings. Svelte doesn't mind.
15+
Để ý rằng giá trị của `<option>` là đối tượng thay vì là dải kí tự. Svelte không quan tâm đâu.
1616

17-
> Because we haven't set an initial value of `selected`, the binding will set it to the default value (the first in the list) automatically. Be careful though — until the binding is initialised, `selected` remains undefined, so we can't blindly reference e.g. `selected.id` in the template.
17+
> Bời vì ta chưa đặt giá trị đầu cho `selected`, phép bind sẽ tự đặt nó thành giá trị mặc định (giá trị đầu tiên trong danh sách). Nhưng bạn phải cẩn trọng — cho đến khi phép bind được khởi chạy, `selected` sẽ vẫn là _undefined_, nên ta không thể lấy giá trị một cách mù quáng, v.d dùng `selected.id` trong template.

content/tutorial/01-svelte/06-bindings/04-select-bindings/app-a/src/lib/App.svelte

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
let questions = [
33
{
44
id: 1,
5-
text: `Where did you go to school?`
5+
text: `Bạn học ở trường gì?`
66
},
77
{
88
id: 2,
9-
text: `What is your mother's name?`
9+
text: `Tên của cha hoặc mẹ bạn?`
1010
},
1111
{
1212
id: 3,
13-
text: `What is another personal fact that an attacker could easily find with Google?`
13+
text: `Bạn có một sự thật nào mà những kẻ tấn công có thể dễ dàng tìm kiếm được trên mạng?`
1414
}
1515
];
1616
@@ -20,12 +20,12 @@
2020
2121
function handleSubmit() {
2222
alert(
23-
`answered question ${selected.id} (${selected.text}) with "${answer}"`
23+
`Câu trả lời #${selected.id} (${selected.text}) "${answer}"`
2424
);
2525
}
2626
</script>
2727

28-
<h2>Insecurity questions</h2>
28+
<h2>Câu hỏi không bảo mật</h2>
2929

3030
<form on:submit|preventDefault={handleSubmit}>
3131
<select
@@ -47,7 +47,7 @@
4747
</form>
4848

4949
<p>
50-
selected question {selected
50+
đã chọn câu hỏi #{selected
5151
? selected.id
5252
: '[waiting...]'}
5353
</p>

content/tutorial/01-svelte/06-bindings/04-select-bindings/app-b/src/lib/App.svelte

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
let questions = [
33
{
44
id: 1,
5-
text: `Where did you go to school?`
5+
text: `Bạn học ở trường gì?`
66
},
77
{
88
id: 2,
9-
text: `What is your mother's name?`
9+
text: `Tên của cha hoặc mẹ bạn?`
1010
},
1111
{
1212
id: 3,
13-
text: `What is another personal fact that an attacker could easily find with Google?`
13+
text: `Bạn có một sự thật nào mà những kẻ tấn công có thể dễ dàng tìm kiếm được trên mạng?`
1414
}
1515
];
1616
@@ -20,12 +20,12 @@
2020
2121
function handleSubmit() {
2222
alert(
23-
`answered question ${selected.id} (${selected.text}) with "${answer}"`
23+
`Câu trả lời #${selected.id} (${selected.text}) "${answer}"`
2424
);
2525
}
2626
</script>
2727

28-
<h2>Insecurity questions</h2>
28+
<h2>Câu hỏi không bảo mật</h2>
2929

3030
<form on:submit|preventDefault={handleSubmit}>
3131
<select
@@ -47,7 +47,7 @@
4747
</form>
4848

4949
<p>
50-
selected question {selected
50+
đã chọn câu hỏi #{selected
5151
? selected.id
5252
: '[waiting...]'}
5353
</p>

content/tutorial/01-svelte/06-bindings/05-group-inputs/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
2-
title: Group inputs
2+
title: Nhóm input
33
---
44

5-
If you have multiple `type="radio"` or `type="checkbox"` inputs relating to the same value, you can use `bind:group` along with the `value` attribute. Radio inputs in the same group are mutually exclusive; checkbox inputs in the same group form an array of selected values.
5+
Nếu bạn có nhiều ô `type="radio"` hoặc `type="checkbox"` mà liên quan đến cùng một giá trị, bạn có thể dùng `bind:group` cùng với thuộc tính `value`. Các ô đánh dấu _(radio input)_ trong cùng một nhóm sẽ loại trừ lẫn nhau (chỉ được chọn một); ô lựa chọn _(checkbox input)_ trong cùng một nhóm sẽ phân thành một mảng nhiều giá trị.
66

7-
Add `bind:group={scoops}` to the radio inputs...
7+
Hãy thêm `bind:group={scoops}` vào các ô đánh dấu...
88

99
```svelte
1010
/// file: App.svelte
@@ -16,7 +16,7 @@ Add `bind:group={scoops}` to the radio inputs...
1616
/>
1717
```
1818

19-
...and `bind:group={flavours}` to the checkbox inputs:
19+
...và thêm `bind:group={flavours}` vào các ô lựa chọn:
2020

2121
```svelte
2222
/// file: App.svelte

content/tutorial/01-svelte/06-bindings/05-group-inputs/app-a/src/lib/App.svelte

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
66
</script>
77

8-
<h2>Size</h2>
8+
<h2>Kích cỡ</h2>
99

1010
{#each [1, 2, 3] as number}
1111
<label>
@@ -15,13 +15,13 @@
1515
value={number}
1616
/>
1717

18-
{number} {number === 1 ? 'scoop' : 'scoops'}
18+
{number} muỗng
1919
</label>
2020
{/each}
2121

22-
<h2>Flavours</h2>
22+
<h2>Hương vị</h2>
2323

24-
{#each ['cookies and cream', 'mint choc chip', 'raspberry ripple'] as flavour}
24+
{#each ['bánh quy và kem', 'socola bạc hà', 'ngũ quả mâm xôi'] as flavour}
2525
<label>
2626
<input
2727
type="checkbox"
@@ -34,12 +34,11 @@
3434
{/each}
3535

3636
{#if flavours.length === 0}
37-
<p>Please select at least one flavour</p>
37+
<p>Hãy chọn một hoặc nhiều hương vị</p>
3838
{:else if flavours.length > scoops}
39-
<p>Can't order more flavours than scoops!</p>
39+
<p>Không thể đặt hương vị nhiều hơn muỗng kem!</p>
4040
{:else}
4141
<p>
42-
You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'}
43-
of {formatter.format(flavours)}
42+
Bạn đã đặt {scoops} muỗng {formatter.format(flavours)}
4443
</p>
4544
{/if}

content/tutorial/01-svelte/06-bindings/05-group-inputs/app-b/src/lib/App.svelte

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
let scoops = 1;
33
let flavours = [];
44
5-
const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
5+
const formatter = new Intl.ListFormat('vi', { style: 'long', type: 'conjunction' });
66
</script>
77

8-
<h2>Size</h2>
8+
<h2>Kích cỡ</h2>
99

1010
{#each [1, 2, 3] as number}
1111
<label>
@@ -16,13 +16,13 @@
1616
bind:group={scoops}
1717
/>
1818

19-
{number} {number === 1 ? 'scoop' : 'scoops'}
19+
{number} muỗng
2020
</label>
2121
{/each}
2222

23-
<h2>Flavours</h2>
23+
<h2>Hương vị</h2>
2424

25-
{#each ['cookies and cream', 'mint choc chip', 'raspberry ripple'] as flavour}
25+
{#each ['bánh quy và kem', 'socola bạc hà', 'ngũ quả mâm xôi'] as flavour}
2626
<label>
2727
<input
2828
type="checkbox"
@@ -36,12 +36,11 @@
3636
{/each}
3737

3838
{#if flavours.length === 0}
39-
<p>Please select at least one flavour</p>
39+
<p>Hãy chọn một hoặc nhiều hương vị</p>
4040
{:else if flavours.length > scoops}
41-
<p>Can't order more flavours than scoops!</p>
41+
<p>Không thể đặt hương vị nhiều hơn muỗng kem!</p>
4242
{:else}
4343
<p>
44-
You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'}
45-
of {formatter.format(flavours)}
44+
Bạn đã đặt {scoops} muỗng {formatter.format(flavours)}
4645
</p>
4746
{/if}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
---
2-
title: Select multiple
2+
title: Chọn nhiều trong select
33
---
44

5-
A `<select>` element can have a `multiple` attribute, in which case it will populate an array rather than selecting a single value.
5+
Một phần tử `<select>` có thể có thuộc tính `multiple`, tức là nó sẽ phân ra thành một mảng thay vì chỉ có chọn một giá trị.
66

7-
Replace the checkboxes with a `<select multiple>`:
7+
Thay các ô đánh dấu với `<select multiple>`:
88

99
```svelte
1010
/// file: App.svelte
11-
<h2>Flavours</h2>
11+
<h2>Hương vị</h2>
1212
1313
+++<select multiple bind:value={flavours}>+++
14-
{#each ['cookies and cream', 'mint choc chip', 'raspberry ripple'] as flavour}
14+
{#each ['bánh quy và kem', 'socola bạc hà', 'ngũ quả mâm xôi'] as flavour}
1515
+++ <option>{flavour}</option>+++
1616
{/each}
1717
+++</select>+++
1818
```
1919

20-
Note that we're able to omit the `value` attribute on the `<option>`, since the value is identical to the element's contents.
20+
Để ý rằng ta có thể bỏ thuộc tính `value` trên `<option>`, vì các giá trị giống với nội dung các phần tử.
2121

22-
> Press and hold the `control` key (or the `command` key on MacOS) to select multiple options.
22+
> Bấm giữ phím `Control` (hoặc `command` trên macOS) để có thể chọn nhiều lựa chọn.

content/tutorial/01-svelte/06-bindings/06-multiple-select-bindings/app-b/src/lib/App.svelte

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
let scoops = 1;
33
let flavours = [];
44
5-
const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
5+
const formatter = new Intl.ListFormat('vi', { style: 'long', type: 'conjunction' });
66
</script>
77

8-
<h2>Size</h2>
8+
<h2>Kích cỡ</h2>
99

1010
{#each [1, 2, 3] as number}
1111
<label>
@@ -16,25 +16,24 @@
1616
bind:group={scoops}
1717
/>
1818

19-
{number} {number === 1 ? 'scoop' : 'scoops'}
19+
{number} muỗng
2020
</label>
2121
{/each}
2222

23-
<h2>Flavours</h2>
23+
<h2>Hương vị</h2>
2424

2525
<select multiple bind:value={flavours}>
26-
{#each ['cookies and cream', 'mint choc chip', 'raspberry ripple'] as flavour}
26+
{#each ['bánh quy và kem', 'socola bạc hà', 'ngũ quả mâm xôi'] as flavour}
2727
<option>{flavour}</option>
2828
{/each}
2929
</select>
3030

3131
{#if flavours.length === 0}
32-
<p>Please select at least one flavour</p>
32+
<p>Hãy chọn một hoặc nhiều hương vị</p>
3333
{:else if flavours.length > scoops}
34-
<p>Can't order more flavours than scoops!</p>
34+
<p>Không thể đặt hương vị nhiều hơn muỗng kem!</p>
3535
{:else}
3636
<p>
37-
You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'}
38-
of {formatter.format(flavours)}
37+
Bạn đã đặt {scoops} muỗng {formatter.format(flavours)}
3938
</p>
4039
{/if}

0 commit comments

Comments
 (0)