为什么 Blazor WASM 不更新状态



我有一个按钮和一条消息,如果条件为真,应该显示。

<button @onclick="Helper.CallFunc">Call async func</button>
@if(Helper.Loading)
{
@("Loading...")
}

LoadingHelper类看起来像这样

public class LoadingHelper
{
public bool Loading { get; private set; } = false;
public Func<Task> PassedFunc { private get; set; } = async () => await Task.Delay(2000);
public Func<Task> CallFunc => async () =>
{
Loading = true;
await PassedFunc();
Loading = false;
};
}

当我像这样定义对象Helper消息确实显示 2000 毫秒

LoadingHelper Helper { get; set; } = new() 
{
PassedFunc = async () => await Task.Delay(2000)
};

但是,当它像这样定义时,消息永远不会显示

LoadingHelper Helper => new() 
{
PassedFunc = async () => await Task.Delay(2000)
};

我在这里有点困惑为什么第二个示例中没有显示Loading更改。无论Helper对象是使用gettersetter设置的,还是仅getter,更改不应该是可见的,因为我没有直接修改Loading属性?

编辑当由于某种原因这样定义时,它可以工作

LoadingHelper Helper { get; } = new()
{
PassedFunc = async () => await Task.Delay(2000)
};

每次调用Func时构建匿名函数的成本很高。

public Func<Task> CallFunc => async () =>
{
Loading = true;
await PassedFunc();
Loading = false;
};

您可以像这样缓存函数:

public Func<Task> CallFunc;
public LoadingHelper()
{
CallFunc = async () =>
{
Loading = true;
await PassedFunc();
Loading = false;
};
}

如果要将"加载程序"应用于组件中的所有 UI 事件,可以创建一个重载标准ComponentBase实现的自定义IHandleEvent.HandleEventAsync。下面是演示如何实现一个的页面。 这仅在loadingMouseEventArgs事件时更新。

@page "/"
@implements IHandleEvent
<h3>Loader Demo</h3>
<div class="m-2">
<button class="btn btn-primary" @onclick=HandleClickAsync>Call async func</button>
<button class="btn btn-dark" @onclick=HandleClickAsync>Call async func</button>
</div>
<div class="m-2">
<input type="checkbox" @onchange=HandleCheckAsync />
</div>
@if (this.Loading)
{
<div class="alert alert-warning">Loading... </div>
}
@code {
protected bool Loading;
private async Task HandleClickAsync()
=> await Task.Delay(2000);
private async Task HandleCheckAsync()
=> await Task.Delay(2000);
async Task IHandleEvent.HandleEventAsync(EventCallbackWorkItem callback, object? arg)
{
if (arg is MouseEventArgs)
Loading = true;
var task = callback.InvokeAsync(arg);
var shouldAwaitTask = task.Status != TaskStatus.RanToCompletion &&
task.Status != TaskStatus.Canceled;
StateHasChanged();
await task;
if (arg is MouseEventArgs)
Loading = false;

StateHasChanged();
}
}

在提出问题之前,我应该多研究一下。答案非常简单,如此处所述。

基本上LoadingHelper Helper => new()返回了一个显然Loading设置为false的新对象。

另一方面,LoadingHelper Helper { get; } = new()每次都返回相同的对象。

相关内容

  • 没有找到相关文章

最新更新