提问人:Alexan 提问时间:5/16/2023 更新时间:5/16/2023 访问量:457
当其他组件发生更改时,我需要更新 blazor 组件的状态
I need to update state of blazor component when other component changed
问:
我有一个包含不同组件的 blazor 页面。
组件结构如下:
page component1 component11 component2
当 component11 上发生事件时,component2 应更新其状态。
在同一个组件上,我使用 event。OnStateChange
对于父组件的更新状态,我也可以使用 EventCallback。
但是在这里,我需要将事件向上传递两个级别,然后向下传递到其他组件。
看起来有点复杂。也许存在一些简单的方法来做到这一点。
事件冒泡可以自动工作吗?也许是一些应用程序设置?
答:
3赞
MrC aka Shaun Curtis
5/16/2023
#1
您需要使用某种形式的通知模式。
这是一个简单的提供程序。请注意,它需要从 DI 到 demo 注入服务。WeatherForecastService
public class TimeStampProvider
{
private readonly WeatherForecastService _weatherForecastService;
public TimeStampProvider(WeatherForecastService weatherForecastService)
=> _weatherForecastService = weatherForecastService;
public event EventHandler? TimeStampChanged;
public string TimeStamp = string.Empty;
public void NotifyTimeStampChanged(string timeStamp)
{
TimeStamp = timeStamp;
this.TimeStampChanged?.Invoke(this, EventArgs.Empty);
}
}
您可以将其注册为作用域内的 DI 服务,或者,如果您在页面范围内使用它,请在页面组件中创建一个实例并级联它。
接下来是几个使用 .TimeStampProvider
TimeStampSetter
<div class="m-2 p-2">
<button class="btn btn-primary" @onclick=this.Clicked>Update Time Stamp</button>
</div>
@code {
[CascadingParameter] private TimeStampProvider myProvider { get; set; } = default!;
protected override void OnInitialized()
{
ArgumentNullException.ThrowIfNull(this.myProvider);
}
private void Clicked()
=> myProvider.NotifyTimeStampChanged(DateTime.Now.ToLongTimeString());
}
时间戳查看器
@implements IDisposable
<div class="bg-dark text-white m-2 p-2">
<pre>Stamp : @myProvider.TimeStamp </pre>
</div>
@code {
[CascadingParameter] private TimeStampProvider myProvider { get; set; } = default!;
protected override void OnInitialized()
{
ArgumentNullException.ThrowIfNull(this.myProvider);
this.myProvider.TimeStampChanged += this.OnChanged;
}
private void OnChanged(object? sender, EventArgs e)
=> this.InvokeAsync(StateHasChanged);
public void Dispose()
=> this.myProvider.TimeStampChanged -= this.OnChanged;
}
我的组件
<div class="bg-secondary m-3 p-2">
<h3>MyComponent</h3>
<TimeStampViewer />
<TimeStampSetter />
</div>
@code {
}
最后是页面,有许多子组件需要保持同步。请注意级联值。fixed
@page "/"
@inject IServiceProvider ServiceProvider
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
<CascadingValue Value=_myStateProvider IsFixed>
<MyComponent />
<TimeStampSetter />
<TimeStampViewer />
<TimeStampViewer />
<TimeStampViewer />
<TimeStampViewer />
<TimeStampViewer />
<TimeStampSetter />
</CascadingValue>
@code {
private TimeStampProvider _myStateProvider = default!;
protected override void OnInitialized()
{
// creates a new instance of TimeStampProvider in the context of the DI service container
// which populates any DI services in the object
_myStateProvider = ActivatorUtilities.CreateInstance<TimeStampProvider>(ServiceProvider);
ArgumentNullException.ThrowIfNull(_myStateProvider);
}
}
测试一下,你会发现一切都保持同步!
评论