You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 08:36:03