首页 > 解决方案 > 如何从 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(这个被修改为使用局部变量,调用方法通过类递增并显示类中的值)

@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(这个是当前值和方法要递增的类)

使用系统;使用 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

标签: blazorblazor-client-side

解决方案


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

测试类.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


推荐阅读