C# Blazor EventCallBack 未设置

问题描述 投票:0回答:1

我是 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(),因此不会在页面上显示新值。

c# .net blazor
1个回答
0
投票

首先,确保您以交互模式运行。 我已将我的项目设置为服务器,但也可以是其中之一。 请注意,当您进行实验时,在服务器模式下调试会更容易、更快捷。

首先我的

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;
    }
}

需要强调的要点是:

  1. 没有
    StateHasChanged
    调用,它们内置于
    ComponentBase
  2. 删除了很多不必要的
    async
    呼叫。
© www.soinside.com 2019 - 2024. All rights reserved.