本文介绍了Blazor-绑定到由另一个组件更改的服务属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
更新(解决方案)
多亏了Magoo先生的回答,我让它正常工作了。该解决方案是通过事件完成的,在官方示例项目FlightFinder中也显示了该解决方案。
请确保使用singleton
:
示例:Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<LoginService, ILoginService>();
}
LoginService.cs:
public event Action OnChange;
public async Task<bool> LoginFromLocalStorageAsync()
{
var response = await _http.PostJsonAsync<TokenResult>("/api/auth", model);
Token = response.Token;
ExpireDate = response.ExpireDate;
_http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Token);
OnChange?.Invoke(); // Here we invoke the event
}
NavMenu.cshtml:
protected override void OnInit()
{
LoginService.OnChange += StateHasChanged;
}
初始问题
我目前正在尝试学习Blazor。我有一个NavMenu
组件,它有多个链接,其中之一是:<a href="login">Login</a>
,只要用户登录,它就应该更改为<a onclick="@Logout">Logout</a>
。使用我自己的服务LoginService
在另一个组件(Login
组件)中登录。
LoginService
具有承载令牌的Token
属性和属性public bool IsLoggedIn => !string.IsNullOrEmpty(Token);
。我尝试在razor视图中使用带有if-else
-语句的简单绑定。这不起作用,我的下一次尝试是在Login
组件中使用StateHasChanged();
,只要有人登录。也不起作用(可能是因为我想更新NavMenu
而不是Login
.)
NavMenu.cshtml:
@inject ILoginService LoginService
@if(LoginService.IsLoggedIn) {
<a href="logout">Logout</a>
}
else {
<a href="login">Login</a>
}
Login.cshtml:
<form onsubmit="@Submit">
<input type="email" placeholder="Email Address" bind="@LoginViewModel.Email" />
<input type="password" placeholder="Password" bind="@LoginViewModel.Password" />
<button type="submit">Login</button>
</form>
@functions
{
public LoginViewModel LoginViewModel { get; } = new LoginViewModel();
public async Task Submit()
{
await LoginService.LoginAsync(LoginViewModel);
}
}
LoginService.cs
public class LoginService : ILoginService
{
private readonly HttpClient _http;
public LoginService(HttpClient http) => _http = http;
public string Token { get; private set; }
public bool IsLoggedIn => !string.IsNullOrEmpty(Token);
public async Task<bool> LoginAsync(LoginViewModel model)
{
try
{
var response = await _http.PostJsonAsync<TokenResult>("/api/auth", model);
Token = response.Token;
return true;
}
catch (Exception)
{
return false;
}
}
}
不幸的是,NavMenu
停留在<a href="login">Login</a>
上。我正在考虑从Login
组件向NavMenu
发送消息。如何使NavMenu
更新其视图?
推荐答案
您可以向LoginService添加事件,只要令牌更改就会引发该事件。
然后您的菜单组件可以订阅该事件(您已经注入了LoginService)并调用StateHasChanged()。
这将刷新视图并更新客户端。
这篇关于Blazor-绑定到由另一个组件更改的服务属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!