我的Blazor MAUI应用程序中有一个类/服务,它定期处理存储在其中的数据。有一个内部调度器,它以固定的间隔重新生成值。
我有一个Blazor组件,它从这个服务中读取值。当我的服务中的值发生变化时,我希望我的Blazor组件能够反映这种变化。
为了简单起见,我们来看看以下内容:
public class EmployeeService {
public int NumberOfEmployees { get; private set; }
public EmployeeService() {
// Logic to initialize a fixed scheduled for function
// RecalculateNumberOfEmployees();
}
private async void RecalculateNumberOfEmployees() {
numberOfEmployees += 1;
}
}
@path "/employees"
@inject EmployeeService Service
Number of employees: @Service.NumberOfEmployees
@code {
}
我在这里找到了一个使用计时器来调用StateHasChanged()
的建议,但我真的,真的不喜欢这种方法。这似乎是一种资源浪费和反模式。
我的下一步是让EmployeeService
接受来自Blazor组件的EventCallback
,并将其存储在列表中。这将允许任何组件侦听EmployeeService
类中的更改。当组件被卸载时,它将删除回调。
类似于:
EmployeeService.cs
public List<EventCallback> listeners { get; private set; } = new List<EventCallback>();
public async void RegisterCallback(EventCallback callback) {
listeners.ForEach(...notify listeners);
}
public async void DeregisterCallback(EventCallback callback) {
listeners.Remove ... etc
}
员工.剃须刀
...
@code {
// register / deregister callback and listen for changes, invoke StateHasChanged()
}
在我走上这条路之前,有没有更好的设计模式可以用于未来更适合这个目的的组件?我觉得这应该已经融入到框架中,但还没有看到任何解决方案
您可以使用事件操作:
EmployeeService.cs
public class EmployeeService
{
public int NumberOfEmployees { get; private set; }
public EmployeeService() {
// Logic to initialize a fixed scheduled for function
// RecalculateNumberOfEmployees();
}
private async void RecalculateNumberOfEmployees() {
numberOfEmployees += 1;
NotifyStateChanged();
}
public event Action OnChange;
private void NotifyStateChanged() => OnChange?.Invoke();
}
员工.剃须刀
@inject EmployeeService EmployeeService
@implements IDisposable
Number of employees: @EmployeeService.NumberOfEmployees
@code {
protected override void OnInitialized()
{
EmployeeService.OnChange += OnChangeHandler;
}
public void Dispose()
{
EmployeeService.OnChange -= OnChangeHandler;
}
private async void OnChangeHandler()
{
await InvokeAsync(StateHasChanged);
}
}
另一种可能性是使用事件聚合器模式。看看这个库:https://github.com/mikoskinen/Blazor.EventAggregator