การผูกข้อมูลและการจัดการเหตุการณ์
ใช้การผูกข้อมูลทางเดียวและสองทาง จัดการเหตุการณ์ของ DOM และคอมโพเนนต์ และใช้ EventCallback
การผูกข้อมูลและการจัดการเหตุการณ์ เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
การผูกข้อมูลใน Blazor
Blazor รองรับการผูกข้อมูลสามทิศทาง: ทางเดียว (อ่านอย่างเดียว, @expr), อิงอีเวนต์ (@onclick และอื่น ๆ) และ สองทาง (@bind) ทั้งหมดนี้เป็นพื้นฐานของส่วนติดต่อผู้ใช้แบบตอบสนอง
การผูกข้อมูลทางเดียว
เพียงแสดงผลนิพจน์ C# ภายในมาร์กอัปโดยใช้ @ ค่าจะอัปเดตทุกครั้งที่คอมโพเนนต์เรนเดอร์ใหม่ แต่ DOM ไม่สามารถส่งค่ากลับไปยัง C# ได้
<!-- One-way: C# -> DOM -->
<p>Count: @_count</p>
<p>Full name: @($"{_firstName} {_lastName}")</p>
<p>Price: @Price.ToString("C")</p>
@code {
private int _count = 0;
private string _firstName = "Alice";
private string _lastName = "Smith";
[Parameter] public decimal Price { get; set; }
}การผูกข้อมูลสองทางด้วย @bind
@bind เชื่อมองค์ประกอบรับข้อมูลเข้ากับฟิลด์โดยใช้ทั้งการกำหนดค่าพร็อพเพอร์ตีและอีเวนต์การเปลี่ยนแปลง ใช้ได้กับข้อความ ตัวเลข วันที่ ช่องทำเครื่องหมาย และรายการแบบเลือก
<input @bind="_name" placeholder="Enter name" />
<input type="number" @bind="_quantity" />
<input type="date" @bind="_dueDate" />
<input type="checkbox" @bind="_isActive" />
<p>Name: @_name | Qty: @_quantity | Active: @_isActive</p>
@code {
private string _name = "";
private int _quantity = 1;
private DateTime _dueDate = DateTime.Today;
private bool _isActive = true;
}@bind กับอีเวนต์แบบกำหนดเอง
โดยค่าเริ่มต้น @bind จะใช้อีเวนต์ onchange ใช้ @bind:event เพื่อเปลี่ยนอีเวนต์ดังกล่าว — ตัวอย่างเช่น oninput จะทำงานทุกครั้งที่กดแป้น เพื่อรองรับการค้นหาแบบสด
@* Updates on every keystroke instead of on focus-loss *@
<input @bind="_search"
@bind:event="oninput"
placeholder="Live search..." />
<ul>
@foreach (var item in Filtered)
{
<li>@item</li>
}
</ul>
@code {
private string _search = "";
private string[] Items = { "Apple", "Banana", "Cherry", "Avocado" };
private IEnumerable<string> Filtered =>
Items.Where(i => i.Contains(_search, StringComparison.OrdinalIgnoreCase));
}การจัดการอีเวนต์ด้วย @onclick
ใช้ @onclick (และคำสั่งอีเวนต์ DOM อื่น ๆ) เพื่อผูกตัวแทนเมธอด C# เข้ากับอีเวนต์ DOM ทั้งเมธอดแบบพร้อมกันและงานแบบอะซิงโครนัสสามารถใช้งานได้
<button @onclick="Increment">+</button>
<button @onclick="DecrementAsync">-</button>
<button @onclick="() => _count = 0">Reset</button>
<p>Count: @_count</p>
@code {
private int _count = 0;
private void Increment() => _count++;
private async Task DecrementAsync()
{
await Task.Delay(200); // simulate async work
_count--;
}
}อาร์กิวเมนต์อีเวนต์
อีเวนต์ DOM จะจัดเตรียมอ็อบเจ็กต์อาร์กิวเมนต์อีเวนต์ ให้ประกาศชนิดอาร์กิวเมนต์ที่เหมาะสมในตัวจัดการ เพื่อเข้าถึงพิกัด รหัสแป้น ค่าข้อมูลที่ป้อน และอื่น ๆ
<input @onkeydown="OnKeyDown" @onfocus="OnFocus" />
<div @onmousemove="OnMouseMove">Move here</div>
<p>@_info</p>
@code {
private string _info = "";
private void OnKeyDown(KeyboardEventArgs e)
=> _info = $"Key: {e.Key} (Ctrl={e.CtrlKey})";
private void OnFocus(FocusEventArgs e)
=> _info = "Input focused";
private void OnMouseMove(MouseEventArgs e)
=> _info = $"Mouse: ({e.ClientX}, {e.ClientY})";
}EventCallback สำหรับการสื่อสารระหว่างคอมโพเนนต์แม่กับลูก
EventCallback คือวิธีของ Blazor สำหรับการสื่อสารจากคอมโพเนนต์ลูกไปยังคอมโพเนนต์แม่ ต่างจาก Action/Func ทั่วไปตรงที่จะเรียก StateHasChanged บนคอมโพเนนต์แม่โดยอัตโนมัติ และจัดการข้อผิดพลาดได้อย่างถูกต้อง
@* Child: ProductCard.razor *@
<button @onclick="() => OnBuy.InvokeAsync(Product)">Buy</button>
@code {
[Parameter] public Product Product { get; set; } = default!;
[Parameter] public EventCallback<Product> OnBuy { get; set; }
}
@* Parent: *@
<ProductCard Product="p" OnBuy="HandleBuy" />
@code {
private async Task HandleBuy(Product p)
{
await CartService.AddAsync(p);
// Parent re-renders automatically
}
}การป้องกันการทำงานเริ่มต้นและการหยุดการเผยแพร่อีเวนต์
ใช้ @onclick:preventDefault เพื่อยกเลิกการทำงานเริ่มต้นของเบราว์เซอร์ และใช้ @onclick:stopPropagation เพื่อหยุดการส่งต่ออีเวนต์ขึ้นตามลำดับชั้น
@* Prevent form submission *@
<form @onsubmit="HandleSubmit" @onsubmit:preventDefault>
<input @bind="_value" />
<button type="submit">Save</button>
</form>
@* Stop click from bubbling to parent div *@
<div @onclick="ParentClicked">
<button @onclick="ChildClicked"
@onclick:stopPropagation>
Click me
</button>
</div>การผูกข้อมูลสองทางด้วย @bind-Value บนคอมโพเนนต์แบบกำหนดเอง
ใช้รูปแบบ Value/ValueChanged บนคอมโพเนนต์แบบกำหนดเอง เพื่อรองรับ @bind-Value จากคอมโพเนนต์แม่ ซึ่งเป็นข้อตกลงมาตรฐานสำหรับการผูกข้อมูลสองทางของ Blazor
@* RatingInput.razor *@
@for (int i = 1; i <= 5; i++)
{
int star = i;
<span class="@(star <= Value ? "filled" : "")"
@onclick="() => ValueChanged.InvokeAsync(star)">★</span>
}
@code {
[Parameter] public int Value { get; set; }
[Parameter] public EventCallback<int> ValueChanged { get; set; }
}
@* Usage: *@
<RatingInput @bind-Value="_rating" />การหน่วงอีเวนต์ข้อมูลเข้า
สำหรับการดำเนินการที่ใช้ทรัพยากรมากและถูกเรียกจากข้อมูลที่ผู้ใช้ป้อน (การเรียก API การกรองข้อมูลปริมาณมาก) ให้หน่วงอีเวนต์โดยใช้ CancellationTokenSource เพื่อชะลอการทำงานจนกว่าผู้ใช้จะหยุดพิมพ์
@code {
private string _query = "";
private CancellationTokenSource? _cts;
private async Task OnSearchInput(ChangeEventArgs e)
{
_query = e.Value?.ToString() ?? "";
_cts?.Cancel();
_cts = new CancellationTokenSource();
try
{
await Task.Delay(300, _cts.Token); // wait 300ms
Results = await SearchService.SearchAsync(_query);
}
catch (TaskCanceledException) { /* user still typing */ }
}
private List<string> Results = new();
}ตรวจสอบความเข้าใจ
EventCallback มีข้อได้เปรียบเหนือ Action/Func อย่างไรสำหรับอีเวนต์จากคอมโพเนนต์ลูกไปยังคอมโพเนนต์แม่ใน Blazor
ทบทวน: การผูกข้อมูลและการจัดการอีเวนต์
ประเด็นสำคัญ:
- การผูกข้อมูลทางเดียว: แสดงนิพจน์ C# ด้วย
@expr - การผูกข้อมูลสองทาง: ใช้
@bindกับองค์ประกอบรับข้อมูล และใช้@bind:eventเพื่อเปลี่ยนตัวกระตุ้น - อีเวนต์ DOM:
@onclick,@oninput,@onkeydownพร้อมอาร์กิวเมนต์อีเวนต์ที่มีชนิดกำกับ EventCallback<T>: การสื่อสารจากคอมโพเนนต์ลูกไปยังคอมโพเนนต์แม่ พร้อมเรียก StateHasChanged อัตโนมัติ- ใช้ Value/ValueChanged เพื่อรองรับการผูกข้อมูลสองทางบนคอมโพเนนต์แบบกำหนดเอง
- หน่วงการดำเนินการที่ใช้ทรัพยากรมากเพื่อลดการเรียก API ที่ไม่จำเป็น
คำถามที่พบบ่อย
บทเรียน “การผูกข้อมูลและการจัดการเหตุการณ์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การผูกข้อมูลและการจัดการเหตุการณ์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การผูกข้อมูลและการจัดการเหตุการณ์”
ใช้การผูกข้อมูลทางเดียวและสองทาง จัดการเหตุการณ์ของ DOM และคอมโพเนนต์ และใช้ EventCallback คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การผูกข้อมูลและการจัดการเหตุการณ์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- รูปแบบคอมโพเนนต์ของ Blazor
- การผูกข้อมูลและการจัดการเหตุการณ์
- การสื่อสารระหว่างคอมโพเนนต์และ DI
- การจัดการสถานะใน Blazor