【问题标题】:Blazor server component isn't rerenderedBlazor 服务器组件未重新呈现
【发布时间】:2021-03-27 21:53:36
【问题描述】:

我有一个带有搜索页面的 Blazor Server (.NETv5) 应用程序。 在此页面上,我有一个按名称搜索的表格。 在表单提交事件中,我调用了子组件的搜索方法。 该组件正在执行实际搜索。这工作正常。
因为搜索可能需要几秒钟的时间,所以我想在搜索开始时显示一个微调器,并在搜索完成时隐藏它。
此外,当我进行第二次搜索时,我想隐藏以前的搜索结果。
隐藏微调器并显示搜索结果有效,但在搜索前显示微调器不起作用。变量设置正确,但页面没有重新呈现(我认为)。

我的页面:

<div class="container pt-2 mb-3">
    <RadzenTemplateForm Data="@searchTerms" Submit="@((SearchTerms args) => { Submit(args); })">
        <div class="row">
            <div class="mb-2 col-6 pl-0">
                <RadzenLabel Text="Name" />
                <RadzenTextBox class="col-12" Name="Name" @bind-Value="searchTerms.Name"/>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12 mt-3">
                <RadzenButton ButtonType="ButtonType.Submit" Icon="search" Text="Search" Disabled="@isSearching" />
                <RadzenButton ButtonStyle="ButtonStyle.Light" Icon="cancel" Text="Cancel" Click="@Cancel" class="ml-2"/>
            </div>
        </div>
    </RadzenTemplateForm>
</div>

<SearchResultsComponent @ref="searchResultsComponent" />
protected SearchTerms searchTerms = new();
protected SearchResultsComponent searchResultsComponent;
protected bool isSearching;

protected void Submit(SearchTerms args)
{
    if (string.IsNullOrEmpty(args.Name)) return;
    
    // Disable submit button ==> NOT WORKING:
    isSearching = true;
    // Call search method on child component
    searchResultsComponent.Search(args);
    // Enable submit button again:
    isSearching = false;
}

protected void Cancel()
{
    // Reset form:
    searchTerms = new SearchTerms();
}

我的子组件:

<div class="container">

    @if (isSearching)
    {
        <div class="spinner-border text-primary mr-2" role="status">
            <span class="sr-only">Searching...</span>
        </div>
        <b>Searching ...</b>
    }

    @if (noResults)
    {
        <div class="alert alert-warning" role="alert">
           No results.
        </div>
    }

    @if (getSearchResults != null && getSearchResults.Any())
    {
        <RadzenHeading Size="H2" Text=@($"Results({getSearchResults.Count})")></RadzenHeading>
        <div class="row">

            @foreach (var searchResult in getSearchResults)
            {
                <RadzenCard>
                    <b>@searchResult.Name</b>
                </RadzenCard>
            }

        </div>
    }

</div>
private IList<MultiShardSearchResultsWerknemer> _searchResults;
private bool _isSearching = true;
private bool _noResults;

protected bool noResults
{
    get => _noResults;
    set
    {
        if (Equals(_noResults, value)) return;
        _noResults = value;
        InvokeAsync(() => StateHasChanged());
    }
}        

protected bool isSearching
{
    get => _isSearching;
    set
    {
        if (Equals(_isSearching, value)) return;
        _isSearching = value;
        InvokeAsync(() => StateHasChanged());
    }
}

protected IList<MultiShardSearchResultsWerknemer> getSearchResults
{
    get => _searchResults;
    set
    {
        if (Equals(_searchResults, value)) return;
        _searchResults = value;
        InvokeAsync(() => StateHasChanged());
    }
}

public void Search(SearchTerms args)
{
    Helpers.ConsoleLog(args);
    if (string.IsNullOrEmpty(args.Name)) return;
    
    // Reset ==> NOT WORKING:
    isSearching = true;
    noResults = false;
    getSearchResults = null;
    InvokeAsync(() => StateHasChanged());

    getSearchResults = ShardingService.SearchForAllEmployees(args.Name, null).GetAwaiter().GetResult();
    Helpers.ConsoleLog("Found results: " + getSearchResults.Count);
    isSearching = false;
    noResults = !getSearchResults.Any();
}

出于调试目的,我设置了_isSearching = true,它显示了微调器。搜索完成后,微调器也会被隐藏,因此可以正常工作。但是当我开始搜索时,我无法显示微调器。 我已经尝试了所有能找到的选项,但没有成功。
我肯定错过了什么。请指教。

【问题讨论】:

    标签: blazor-server-side


    【解决方案1】:

    看看你的搜索方法

    
    protected void Submit(SearchTerms args)
    {
        if (string.IsNullOrEmpty(args.Name)) return;
        
        // Disable submit button ==> NOT WORKING:
        isSearching = true;
        // Call search method on child component
        searchResultsComponent.Search(args);
        // Enable submit button again:
        isSearching = false;
    }
    
    

    请记住,渲染将在方法完成后进行。所以,在调用isSearching 之前是false,之后也是false。这就是你看不到微调器的原因。

    Blazor 提供了一种启动新渲染周期的方法:StateHasChanged()。

    所以,你可以像这样修改提交方法

    protected void Submit(SearchTerms args)
    {
        if (string.IsNullOrEmpty(args.Name)) return;
        
        isSearching = true;
        StateHasChanged()
    
        // Call search method on child component
        searchResultsComponent.Search(args);
    
        isSearching = false;
        StateHasChanged()
    }
    

    那么,你点击搜索/提交按钮就执行了这个方法。

    或者,如果您愿意,也可以创建一个属性

    @code
    {
        private Boolean isSearching = false;
    
        public Boolean IsSearching
        {
            get => isSearching;
            private set
            {
                isSearching = value;
                StateHasChanged();
            }
        }
    
        protected void Submit(SearchTerms args)
        {
            if (string.IsNullOrEmpty(args.Name)) return;
    
            IsSearching = true;
    
            // Call search method on child component
            searchResultsComponent.Search(args);
    
            IsSearching = false;
        }
    }
    

    我没有测试过,但曾经遇到过类似的问题。

    【讨论】:

    • 感谢您的建议。正如您在我的帖子中看到的那样,我已经有一个属性并且正在属性中调用StateHasChanged(),并且还尝试在其他位置调用它,但仍然没有显示微调器。
    • 抱歉。我真的没看到。
    猜你喜欢
    • 2021-01-28
    • 2020-11-04
    • 2020-07-17
    • 2021-10-07
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 2019-09-12
    • 1970-01-01
    相关资源
    最近更新 更多