如何在 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 的一点是,如果一个级联值发生变化,那么新值将被发送到组件树中,所有使用它的组件都将被更新。但如果值不断变化,这可能会产生性能问题。
如何在 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 的一点是,如果一个级联值发生变化,那么新值将被发送到组件树中,所有使用它的组件都将被更新。但如果值不断变化,这可能会产生性能问题。