Blazor单例服务注入组件层级后页面未重新渲染问题
问题根源
你的问题出在MyService没有实现属性变更通知机制。Blazor组件不会自动监听普通类的属性变化:点击Component1的按钮修改Counter后,Index组件根本不知道数据已经更新,自然不会触发重新渲染;而Clear Count能生效,只是因为你手动调用了StateHasChanged()强制刷新了Index组件。
解决方案
通过让服务实现INotifyPropertyChanged接口,让属性变化时主动通知所有订阅的组件,实现自动渲染更新。
1. 改造MyService,添加属性变更通知
using System.ComponentModel; using System.Runtime.CompilerServices; namespace Injection.Pages { public class MyService : INotifyPropertyChanged { private int _counter; public int Counter { get => _counter; set { if (_counter != value) { _counter = value; OnPropertyChanged(); } } } public void increaseCount() { Counter += 1; } public void clearCounter() { Counter = 0; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }
2. 修改Index组件,订阅服务的变更通知
让Index组件监听服务的PropertyChanged事件,当Counter变化时自动刷新:
@page "/" @inject MyService myService @implements IDisposable <h3>Injection</h3> <button @onclick="clearCounter">Clear Count</button> <br /> <br /> @myService.Counter <Component1 myService="myService" /> @code { protected override void OnInitialized() { // 订阅Counter属性变更事件 myService.PropertyChanged += (sender, args) => { if (args.PropertyName == nameof(MyService.Counter)) { StateHasChanged(); } }; } private void clearCounter () { myService.clearCounter(); // 现在不需要手动调用StateHasChanged(),属性变更通知会自动触发刷新 } // 组件销毁时取消订阅,避免内存泄漏 public void Dispose() { myService.PropertyChanged -= (sender, args) => { if (args.PropertyName == nameof(MyService.Counter)) { StateHasChanged(); } }; } }
3. 优化Component1组件(可选)
Component1本身没有绑定Counter的显示,所以点击按钮后不需要调用StateHasChanged():
<h3>Component1</h3> <button @onclick="increaseCount">Increase Count</button> @code { [Parameter] public MyService myService { get; set; } private void increaseCount() { myService.increaseCount(); // 移除不必要的StateHasChanged()调用 } }
内容的提问来源于stack exchange,提问作者Axium7
相关产品推荐
相关产品推荐

