【问题标题】:Blazor Multiple change events not updating property correctlyBlazor 多个更改事件未正确更新属性
【发布时间】:2020-05-11 05:38:01
【问题描述】:

我是 blazor 的新手,很高兴开始为我们的一些内部应用程序尝试它,但是我在理解绑定/更改事件时遇到了一些麻烦。从一个新的 Blazor 项目开始,我添加了一个 AppService 单例并将该服务注入到一个新页面(建筑物)和我的导航菜单中。在导航菜单和构建页面上,我都有一个绑定到服务属性的复选框,即。

当我更改复选框时,它会更新该页面上的服务属性,但不会更新内容区域页面上的属性。我做错了什么?

更新:我确实尝试在此处实施解决方案:Blazor - razor page not updating after property from DI Service is changed,但不幸的是,当我这样做时,我的应用程序甚至无法运行。 =((程序“[26772] iisexpress.exe”已退出,代码为-1073741819(0xc0000005)“访问冲突”。)

应用服务。

public class AppService 
{
    public bool IsAdmin { get; set; } = true;
    public event Action OnChange;
    private void NotifyDataChanged() => OnChange?.Invoke();
}

Startup.cs 配置服务方法

services.AddSingleton<Services.AppService>();

导航菜单。

@inject Services.AppService AppService
<div class="top-row pl-4 navbar navbar-dark">
    <a class="navbar-brand" href="">Staff Management</a>
    <button class="navbar-toggler" @onclick="ToggleNavMenu">
        <span class="navbar-toggler-icon"></span>
    </button>
</div>

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<ul class="nav flex-column">
    <li class="nav-item px-3">
        <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
            <span class="oi oi-home" aria-hidden="true"></span> Home
        </NavLink>
    </li>
    <li class="nav-item px-3">
        <NavLink class="nav-link" href="counter">
            <span class="oi oi-plus" aria-hidden="true"></span> Counter
        </NavLink>
    </li>
    <li class="nav-item px-3">
        <NavLink class="nav-link" href="fetchdata">
            <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
        </NavLink>
    </li>
    <li class="nav-item px-3">
        <NavLink class="nav-link" href="/buildings">
            <span class="oi oi-list-rich" aria-hidden="true"></span> Buildings
        </NavLink>
    </li>
    <li class="nav-item px-3">
        IsAdmin: <input type="checkbox" @bind="@AppService.IsAdmin" />
        <span style="color:#fff;">@AppService.IsAdmin</span>
    </li>
</ul>
</div>

@code {
private bool collapseNavMenu = true;

private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;

private void ToggleNavMenu()
{
    collapseNavMenu = !collapseNavMenu;
}

private void AdminChanged()
{
    AppService.IsAdmin = !AppService.IsAdmin;
    //trying to manually call state change here since below wasn't working
    StateHasChanged();
}

protected override void OnInitialized()
{
    AppService.OnChange += AdminChanged; //also tried AppService.OnChange += StateHasChanged;
}
}

建筑物.razor

@page "/buildings"
@inject Services.AppService AppService
<h3>Buildings IsAdmin: @AppService.IsAdmin</h3>

<input type="checkbox" @bind="@AppService.IsAdmin"/>
@code {

protected override void OnInitialized()
{
    AppService.OnChange += StateHasChanged;
}
}

总的来说,我想要实现的是:创建一个属性,我可以在我的所有页面/组件中使用它来有条件地显示/执行操作。

我希望如果我单击建筑物页面上的复选框,导航菜单将使用来自服务的新值进行更新,但不会发生。或者单击 navmenu 上的复选框将更新 building.razor 页面。

非常感谢任何帮助。也许我没有正确理解某些东西。谢谢!!

【问题讨论】:

    标签: .net asp.net-core razor dependency-injection blazor


    【解决方案1】:

    这可能与您的服务根本没有触发事件有关。 IsAdmin 属性应检查其值是否已更改,如果已更改,则应引发事件。试试这个代码 sn-p。通知事件处理器的类型NotifyDataChanged...是Func&lt;Task&gt;

    public class AppService 
    {
       private bool isAdmin = true;
       public bool IsAdmin 
       { 
         get { return isAdmin; }
         set 
         { 
            if(isAdmin != value)
            {
                isAdmin = value; 
    
                if (NotifyDataChanged != null)
                {
                    await NotifyDataChanged?.Invoke();
                }
            }
         } 
       } 
       public event Func<Task> NotifyDataChanged;
    
     }
    

    建筑物.razor

    @page "/buildings"
    @inject Services.AppService AppService
    @implements IDisposable 
    
    <h3>Buildings IsAdmin: @AppService.IsAdmin</h3>
    
    <input type="checkbox" @bind="@AppService.IsAdmin"/>
    @code {
    
        public async Task OnNotifyDataChanged()
        {
            await InvokeAsync(() =>
            {
                StateHasChanged();
            });
        }
    
    
        protected override void OnInitialized()
        {
            AppService.NotifyDataChanged += OnNotifyDataChanged;
        }
        public void Dispose()
        {
            AppService.NotifyDataChanged -= OnNotifyDataChanged;
        }
    

    尝试并报告...

    【讨论】:

    • 谢谢!这正是问题所在。感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 2020-04-08
    • 1970-01-01
    • 2020-03-02
    相关资源
    最近更新 更多