Blazor:如何让同一组件在两个不同页面使用相互独立的状态
Blazor多页面复用组件独立状态实现方案
原实现报错原因
编译报错本质为类型不匹配问题:Counter组件的CounterService参数声明为CounterService实现类类型,但页面注入的是ICounterServiceA/ICounterServiceB接口类型,接口无法隐式转换为实现类,因此触发转换错误。
原本通过双接口注册获取独立Scoped实例的思路可行,但需要额外做类型转换,且后续扩展更多独立状态时需要新增接口,维护成本较高,最终采用的按键值隔离状态的方案扩展性更强,实现更简洁。
最终实现方案
1. 定义基础计数器服务
CounterService.cs
namespace TestTwoInterfaceToOneService.Shared { public class CounterService { public int CurrentCount { get; set; } public void IncrementCount() { CurrentCount++; } public void ResetCount() { CurrentCount = 0; } } }
2. 实现状态隔离容器服务
CounterStateService.cs
using System.Collections.Generic; namespace TestTwoInterfaceToOneService.Shared { public interface ICounterStateService { CounterService this[string key] { get; } } public class CounterStateService : ICounterStateService { private Dictionary<string, CounterService> counterServices = new(); public CounterService this[string key] { get { if (!counterServices.ContainsKey(key)) { counterServices.Add(key, new CounterService()); } return counterServices[key]; } } } }
3. 注册容器服务
在Program.cs中添加服务注册逻辑:
builder.Services.AddScoped<ICounterStateService, CounterStateService>();
4. 实现复用计数器组件
Counter.razor
<p>Current count: @CounterService.CurrentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Increment</button> @code { [Parameter] public CounterService CounterService { get; set; } private void IncrementCount() { CounterService.CurrentCount++; } }
5. 多页面调用组件
PageA.razor
@page "/pagea" @inject ICounterStateService CounterStateService <h3>Page A</h3> <Counter CounterService='CounterStateService["A"]' /> <button class="btn btn-primary" @onclick='CounterStateService["A"].ResetCount'>Reset Count</button>
PageB.razor
@page "/pageb" @inject ICounterStateService CounterStateService <h3>Page B</h3> <Counter CounterService='CounterStateService["B"]' /> <button class="btn btn-primary" @onclick='CounterStateService["B"].ResetCount'>Reset Count</button>
该方案通过字典存储不同key对应的计数器实例,实现了同一组件在不同页面的状态完全隔离,后续如果需要新增更多独立状态的计数器使用场景,只需要传入新的key即可,不需要修改服务定义。
内容的提问来源于stack exchange,提问作者Dennis Jones
相关产品推荐
相关产品推荐

