我是 Blazor 新手,正在尝试一些东西,但在尝试触发回调时遇到了问题。 我的父级是 Home.razor 并包含:
@page "/"
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
Increment:
<!-- Use @bind for two-way binding -->
<input type="number" @bind="_incrementAmount" />
<p>Increment amount: @_incrementAmount</p>
<Counter IncrementAmount="_incrementAmount"
OnOddCount="@(async (count) => await OddCountDetected(count))"
OnEvenCount="@(async (count) => await EvenCountDetected(count))">
</Counter>
<div style="color: red; height: @Count; min-height:5px; background-color:burlywood; overflow:auto;">
<p>
Odd? @_odd.ToString()
</p>
</div>
@code {
private int _incrementAmount { get; set; } = 1;
private int _count { get; set; }
private bool _odd;
public string Count
{
get { return _count + "px"; }
set { _count = int.Parse(value); }
}
public async Task OddCountDetected(int count)
{
Console.WriteLine($"OddCountDetected called in Home.razor with count: {count}"); // Debug log
_count = count;
_odd = true;
StateHasChanged(); // Refresh the UI
}
public async Task EvenCountDetected(int count)
{
Console.WriteLine($"EvenCountDetected called in Home.razor with count: {count}"); // Debug log
_odd = false;
StateHasChanged(); // Refresh the UI
}
}
我的孩子名为 Counter.razor 并包含以下代码
@page "/counter"
@rendermode InteractiveServer
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
[Parameter]
public int IncrementAmount { get; set; } = 1;
[Parameter]
public EventCallback<int> OnOddCount { get; set; }
[Parameter]
public EventCallback<int> OnEvenCount { get; set; }
private async Task IncrementCount()
{
currentCount += IncrementAmount;
Console.WriteLine($"Incrementing: Current count = {currentCount}, IncrementAmount = {IncrementAmount}");
// Check if OnOddCount or OnEvenCount should be invoked
if (int.IsOddInteger(currentCount))
{
Console.WriteLine($"Odd count detected: {currentCount}"); // Log when odd is detected
// Check if there is an assigned delegate
if (OnOddCount.HasDelegate)
{
Console.WriteLine("Invoking OnOddCount callback"); // Log when callback is invoked
await OnOddCount.InvokeAsync(currentCount);
}
else
{
Console.WriteLine("OnOddCount has no delegate");
}
}
else
{
Console.WriteLine($"Even count detected: {currentCount}"); // Log when even is detected
// Check if there is an assigned delegate
if (OnEvenCount.HasDelegate)
{
Console.WriteLine("Invoking OnEvenCount callback"); // Log when callback is invoked
await OnEvenCount.InvokeAsync(currentCount);
}
else
{
Console.WriteLine("OnEvenCount has no delegate");
}
}
}
}
在这种情况下,每次我触发 IncrementCount() 方法 OnOddCount.HasDelegate 和 OnEvenCount.HasDelegate 都是 false。
我尝试使用以下代码更改设置委托的方式:
<Counter IncrementAmount="_incrementAmount"
OnOddCount="@this.OddCountDetected"
OnEvenCount="@this.EvenCountDetected">
</Counter>
&&
<Counter IncrementAmount="_incrementAmount"
OnOddCount="@OddCountDetected"
OnEvenCount="@EvenCountDetected">
</Counter>
我也尝试过这个问题中所说的答案: Blazor EventCallback 参数未触发
但即使我尝试了,它仍然没有设置好。
此外,另一个症状可能是 @_incrementAmount 不会触发 StateHasChanged(),因此不会在页面上显示新值。
首先,确保您以交互模式运行。 我已将我的项目设置为服务器,但也可以是其中之一。 请注意,当您进行实验时,在服务器模式下调试会更容易、更快捷。
首先我的
App
显示已启用全局交互功能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="SO79018875.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet @rendermode="InteractiveServer" />
</head>
<body>
<Routes @rendermode="InteractiveServer" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
柜台页面
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
[Parameter] public int IncrementAmount { get; set; } = 1;
[Parameter] public EventCallback<int> OnOddCount { get; set; }
[Parameter] public EventCallback<int> OnEvenCount { get; set; }
private async Task IncrementCount()
{
currentCount += IncrementAmount;
Console.WriteLine($"Incrementing: Current count = {currentCount}, IncrementAmount = {IncrementAmount}");
// Check if OnOddCount or OnEvenCount should be invoked
if (int.IsOddInteger(currentCount))
{
Console.WriteLine($"Odd count detected: {currentCount}"); // Log when odd is detected
// Check if there is an assigned delegate
if (OnOddCount.HasDelegate)
Console.WriteLine("Invoking OnOddCount callback"); // Log when callback is invoked
else
Console.WriteLine("OnOddCount has no delegate");
// Just call it. It handles a null delegate
await OnOddCount.InvokeAsync(currentCount);
}
else
{
Console.WriteLine($"Even count detected: {currentCount}"); // Log when even is detected
// Check if there is an assigned delegate
if (OnEvenCount.HasDelegate)
Console.WriteLine("Invoking OnEvenCount callback"); // Log when callback is invoked
else
Console.WriteLine("OnEvenCount has no delegate");
await OnEvenCount.InvokeAsync(currentCount);
}
}
}
和主页:
@page "/"
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
Increment:
<!-- Use @bind for two-way binding -->
<input class="form-control mb-3" type="number" @bind="_incrementAmount" />
<p>Increment amount: @_incrementAmount</p>
<Counter IncrementAmount="_incrementAmount"
OnOddCount="OddCountDetected"
OnEvenCount="EvenCountDetected">
</Counter>
<div class="bg-dark text-white m-2 p-2" >
<pre>
Odd? @_odd.ToString()
</pre>
</div>
@code {
private int _incrementAmount { get; set; } = 1;
private int _count { get; set; }
private bool _odd;
public Task OddCountDetected(int count)
{
Console.WriteLine($"OddCountDetected called in Home.razor with count: {count}");
_count = count;
_odd = true;
return Task.CompletedTask;
}
public Task EvenCountDetected(int count)
{
Console.WriteLine($"EvenCountDetected called in Home.razor with count: {count}");
_odd = false;
return Task.CompletedTask;
}
}
需要强调的要点是:
StateHasChanged
调用,它们内置于 ComponentBase
。async
呼叫。