我有一个按钮和一条消息,如果条件为真,应该显示。
<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
对象是使用getter
和setter
设置的,还是仅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
。下面是演示如何实现一个的页面。 这仅在loading
是MouseEventArgs
事件时更新。
@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()
每次都返回相同的对象。