如何从 Blazor 中的组件以单例形式更新 属性?

How to get updated property in singleton from a component in Blazor?

我刚刚更改了默认的 Blazor 示例来说明这个问题。

MainLayout.razor(这是页面的顶部,只是替换了关于显示计数器)

@inherits LayoutComponentBase
@inject TestClass testClass
<div class="sidebar">
   <NavMenu />
</div>

<div class="main">
  <div class="top-row px-4">
    Counter: @testClass.Counter
</div>

<div class="content px-4">
    @Body
</div>

Counter.razor(这个被修改为使用局部变量,调用方法通过 class 递增并显示来自 class)

@page "/counter"
@inject TestClass testClass
<h1>Counter</h1>

<p>Current count:@testClass.Counter</p>

<button class="btn btn-primary" @onclick="(e => testClass.Increment())">Click me</button>

@code {

}

TestClass.cs(这个是class加上当前值和递增的方法)

正在使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Threading.Tasks;

namespace TestBlazor.Classes
{
   public class TestClass
    {
     public int Counter { get; set; } = 10;
     public void Increment() {
        Counter++;
     }
 }
}

这是按几次增量按钮后的结果:

因此,页面本身可以在每次更改时显示当前值,但是页面顶部的组件不能。它只是显示默认值 10。

这也是我的Program.cs

using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using TestBlazor.Classes;

namespace TestBlazor
{
  public class Program
  {
    public static async Task Main(string[] args)
    {
        var builder = WebAssemblyHostBuilder.CreateDefault(args);
        builder.RootComponents.Add<App>("app");

        builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
        builder.Services.AddSingleton<TestClass>();

        await builder.Build().RunAsync();
    }
  }
}

使用 Core5

您需要通知 MainLayout 组件其状态已更改,并且他应该重新呈现。这可以通过定义每当计数器变量递增时执行的事件委托来实现:

TestClass.cs

public class TestClass
    {
        public int Counter { get; set; } = 10;
        public void Increment()
        {
            Counter++;
            Notify?.Invoke();
        }
        public event Action Notify;
    }

将此代码添加到 MainLayout 页面

@code{
    protected override void OnInitialized()
    {
        testClass.Notify += () => InvokeAsync(StateHasChanged);

        base.OnInitialized();
    }
}

您还必须实施 IDisposable