如何在 BLAZOR 中声明全局变量模型?

How Can I Declare A Global Variables Model In BLAZOR?

如何在 BLAZOR WASM 中声明全局变量模型? 假设我有以下模型,我希望能够在整个项目(页面、服务、组件等)的任何位置访问模型中的每个变量。 你能帮帮我吗?

public class UserInfoGlobalClass
{
    public string User_Name { get; set; } = "JOHN SMITH";
    public string User_Email { get; set; } = "JOHNSMITH@gmail.com";
    public string User_Role { get; set; } = "Administrator";
    public string USER_ID { get; set; } = "85f04683-0d37-4947-a09d-bbb464a92480";

}

您可以将 class 作为单例服务注入:

builder.Services.AddSingleton<UserInfoGlobalClass>();

在服务中包含 class 作为 ctor 参数。

在组件或页面中: @inject UserInfoGlobalClass UserInfoGlobalClass

但这是动态的。您需要使用一个事件来修饰您的 class,以通知页面和组件在内容更新时调用 StateHasChanged()。我通常将属性设置为私有集并公开一个方法来更改它们,最终调用事件来通知侦听器。

public class UserInfoGlobalClass
{
    public string User_Name { get; private set; } = "JOHN SMITH";
    public string User_Email { get; set; } = "JOHNSMITH@gmail.com";
    public string User_Role { get; set; } = "Administrator";
    public string USER_ID { get; set; } = "85f04683-0d37-4947-a09d-bbb464a92480";
    
    public event EventHandler UserChangedEvent;

    public void SetUser(User user)
    {
        User_Name = user.Name;
        ... repeat for properties.
        UserChangedEvent?.Invoke();
    }
}

在其他服务中使用。

builder.Services.AddScoped<SomeOtherService>();
public class SomeOtherService : IDisposable
{

    private readonly UserInfoGlobalClass userInfoGlobalClass;

    public SomeOtherService(UserInfoGlobalClass userInfoGlobalClass)
    {
        this.userInfoGlobalClass = userInfoGlobalClass;
        userInfoGlobalClass.UserChangedEvent += UserChanged;
    }

    public void UserChanged(object sender, EventArgs e)
    {
        // Process user details change.
    }

    public void SetNewUserMethod()
    {
         userInfoGlobalClass.SetUser(new User { ... });
    }

    
    public void Dispose() => userInfoGlobalClass.UserChangedEvent -= UserChanged;
}

在页面或组件中:

@implements IDisposable
@inject UserInfoGlobalClass UserInfoGlobalClass

...

@code {
    protected override void OnInitialized()
    {
        userInfoGlobalClass.UserChangedEvent += StateHasChanged;  
    }
    
    public void public void Dispose() => userInfoGlobalClass.UserChangedEvent -= StateHasChanged;
}

使用 CascadingParameter 怎么样?快速示例:

要使您的变量在所有组件中可用:

在 MainLayout.razor - 在 @code 部分:

 private UserInfoGlobalClass userInfo = new UserInfoGlobalClass();

在 MainLayout.razor - @Body 部分周围:

  <CascadingValue Value="@userInfo">
      @Body
  </CascadingValue>

然后,在您需要访问 UserInfoGlobalClass 对象的任何组件中 - 在 @code 部分:

  [CascadingParameter]
  public UserInfoGlobalClass? userInfo { get; set; }

要在服务中使用这些变量:

在我的例子中,我只是将对象或所需变量作为参数传递给需要使用它的服务:

MyComponent.razor:

{
    await MyService.Get(userInfo);
}

MyService.cs:

public List<MyObject> Get(UserInfoGlobalClass userInfo)
{
   //...service logic here
}

在我自己的项目中,我使用它,例如,当我需要将 CurrentUser (ApplicationUser) 传递给整个项目中的多个组件时,并且只想加载当前用户一次。您可以阅读有关使用级联参数的更多信息 here.

但是,使用级联参数could have drawback and trade-offs。我喜欢 Cascading Parameters 的一点是,如果一个级联值发生变化,那么新值将被发送到组件树中,所有使用它的组件都将被更新。但如果值不断变化,这可能会产生性能问题。