Blazor-更改DI Service中的属性后,剃须刀页面未更新 [英] Blazor - razor page not updating after property from DI Service is changed

查看:125
本文介绍了Blazor-更改DI Service中的属性后,剃须刀页面未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用dotnet 3.1.100-preview2-014569

Using dotnet 3.1.100-preview2-014569

好,请考虑以下示例:

从模板创建一个新的Blazor WebAssemply项目,然后添加以下内容:

Create a new Blazor WebAssemply project from template, then add the following:

books.razor

@page "/books"
@inject BookService bookService

@if (bookService.isLoaned)
{
    <p><em>Book loaned</em></p>
}
else
{
    <p><em>Book returned</em></p>
}

BookService.cs

public class BookService
    {
        public int BookId { get; set; }

        public string Title { get; set; }

        public bool isLoaned { get; set; }
    }

Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<BookService>();
        }

NavMenu.razor

@inject BookService bookService;
<div class="top-row pl-4 navbar navbar-dark">
    <a class="navbar-brand" href="">BlazorBlank_PV2</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="books" @onclick="LoanBookClicked">
                <span class="oi oi-plus" aria-hidden="true"></span>Loan Book
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="books" @onclick="ReturnBookClicked">
                <span class="oi oi-list-rich" aria-hidden="true"></span>Return Book
            </NavLink>
        </li>
    </ul>
</div>

@code {
    private bool collapseNavMenu = true;

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

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

    private void LoanBookClicked()
    {
        bookService.isLoaned = true;       
    }
    private void ReturnBookClicked()
    {
        bookService.isLoaned = false;
    }


}

会发生什么:

预期的行为: 单击菜单项借用书"时,页面应显示借用书",或者如果我单击退还书",则应显示已退还书".但这只会在我单击另一个页面(例如主页")然后再次返回时发生.

Expected behavior: When clicking on the menu item Loan Book the page should show Book Loaned or if I click Return Book it should say Book returned. But this only happens if I click to another page, like Home, and then back again.

即使页面已经在同一页面上,如何强制页面重新呈现/重新检查BookService中的更新值?

How can I force the page to re-render/re-check updated values from BookService even when it's on the same page already?

谢谢!

推荐答案

这是我在BookService类中实现INotifyPropertyChanged接口的新解决方案.为什么要使用此界面?

Here's a new solution in which I implement the INotifyPropertyChanged intereface in the BookService class. Why use this interface ?

  • 它也可以应用于其他属性

  • It can be applied to other properties as well

通知客户属性值已更改是良好服务的重要组成部分,并且不仅限于为此目的而调用StateHasChanged.

Notifying clients that a property value has changed is essential part of good services, and this is not limited to only call the StateHasChanged solely for this purpose.

实现了INotifyPropertyChanged接口,我可以将事件数据传递给已注册或订阅的对象.

With the INotifyPropertyChanged intereface implemented, I can pass event data to registered or subscribing objects.

重要:调用诸如bookService.SetLoanedState(false)之类的更新属性值的方法是不好的编程和反模式设计.一个属性可以有两个访问器,即get和set,它们应用于获取值和更改值.方法有不同的作用...

Important: Calling a method to update a property value like bookService.SetLoanedState(false) is a bad programming and an anti-patterns design. A property can have two accessors, get and set, and they should be used to get a value and to change a value. Methods have different roles...

BookService.cs

BookService.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;



public class BookService : INotifyPropertyChanged
    {
        private bool isLoaned;
        public event PropertyChangedEventHandler PropertyChanged;

        public int BookId { get; set; }

        public string Title { get; set; }


        public bool IsLoaned
        {
            get
            {
                return this.isLoaned;
            }

            set
            {
                if (value != this.isLoaned)
                {
                    this.isLoaned = value;
                    NotifyPropertyChanged();
                }
            }
        }


        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

Books.razor

@page "/books"
@inject BookService bookService
@using System.ComponentModel


@if (bookService.IsLoaned)
{
    <p><em>Book loaned</em></p>
}
else
{
    <p><em>Book returned</em></p>
}

@code{

    protected override void OnInitialized()
    {
        bookService.PropertyChanged += PropertyHasChanged;
    }
    private void PropertyHasChanged(object sender, PropertyChangedEventArgs args)
    {
         StateHasChanged();
    }
}

NavMenu.razor

@code {

    // Code removed for brevity

    private void LoanBookClicked()
    {
        bookService.IsLoaned = true;      
    }
    private void ReturnBookClicked()
    {
        bookService.IsLoaned = false;      
    }
}

希望这行得通...

这篇关于Blazor-更改DI Service中的属性后,剃须刀页面未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆