我正在从事Blazor项目(.NET5).我在组件渲染方面遇到了问题. 我有父组件,里面有ChildContentRenderFragment.我是这样使用它的:

<ParentComponent>
    <ChildComponent1 Title="Component1"></ChildComponent1>
    <ChildComponent2 Title="Component2" SampleEnum="SampleEnum.Bar"></ChildComponent2>
</ParentComponent>

ChildComponent个人继承ChildComponentBase个:

public class ChildComponent1 : ChildComponentBase 
{
   // some code
}

ChildComponentBase包含ParentComponent作为级联参数和2个参数:其中一个是string(Immutable for Blazor Change Detection API),另一个是enum(不是一成不变的),仅作为示例.在这里,我们也

public partial class ChildComponentBase
{
     [CascadingParameter]
     public ParentComponent Parent { get; set; } = default !;

     [Parameter]
     public string? Title { get; set; } // Immutable

     [Parameter]
     public SampleEnum SampleEnum { get; set; } // not Immutable
}

ParentComponent中,我使用了延迟呈现的策略.Defer组件如下所示,并在ParentComponent中使用:

// This is used to move its body rendering to the end of the render queue so we can collect
// the list of child components first.
public class Defer : ComponentBase
{
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    protected override void BuildRenderTree( RenderTreeBuilder builder )
    {
        builder.AddContent( 0, ChildContent );
    }
}

在我的第一次渲染时的项目中,我从ChildContent中收集所有ChildComponent,如下所示:

ChildComponentBase.razor

@{
    Parent.AddChild(this); // Parent is cascading parameter
}

然后我调用回调来处理数据.ParentComponent看起来是这样的: ParentComponent.razor

<CascadingValue Value="this" IsFixed>
    @{
        StartCollectingChildren();
    }
    @ChildContent

    <Defer>
        @{
            FinishCollectingChildren();

            ProcessDataAsync();
        }

        @foreach (var o in _childComponents)
        {
            <p>@o.Title</p>
        }
    </Defer>
</CascadingValue>

ParentComponent.razor.cs

public partial class ParentComponent
{
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    private List<ChildComponentBase> _childComponents = new();
    private bool _firstRender = true;
    private bool _collectingChildren; // Children might re-render themselves arbitrarily. We only want to capture them at a defined time.

    protected async Task ProcessDataAsync()
    {
        if (_firstRender)
        {
            //imitating re-render just like it would be an async call
            await InvokeAsync(StateHasChanged);
            _firstRender = false;
        }
    }

    public void AddChild(ChildComponentBase child)
    {
        _childComponents.Add(child);
    }

    private void StartCollectingChildren()
    {
        _childComponents.Clear();
        _collectingChildren = true;
    }

    private void FinishCollectingChildren()
    {
        _collectingChildren = false;
    }
}

由于调用了回调-发生了重新渲染.由于重新渲染,StartCollectingChildren()再次被调用.这次在第二次渲染ParentComponent时,ChildComponent1不会重新渲染,因为Blazor Change Detection API会跳过它(因为它只包含一个不可变的参数Title,而ChildComponent2另外还包含enum个参数).

Question: how to make this 100 get re-rendered anyway?

我还添加了一个带有上述代码的Sample Project,供您亲自试用.

我试了所有我能在谷歌上找到的东西.我发现的最好的解决办法是在第一次渲染时缓存子集合,但它看起来很脏,可能会在future 引发问题.

推荐答案

您的问题的快速解决方案是修改级联并移除IsFixed.

一旦这样做了,捕获级联的任何组件都将始终被呈现,因为this是一个对象,因此没有通过相等判断.

您还可以使用GUID级联在没有对象参数的子组件上驱动渲染事件.无论何时要强制对捕获级联的任何子组件进行渲染,都会将新的GUID指定给映射参数.

Asp.net相关问答推荐

AJAX返回未定义、失败

Reaction-Native SignalR连接在调试模式下工作,在释放模式下失败

RNGCryptoServiceProvider - 随机数审核

如何注册路由区域

*不*使用 asp.net 会员提供程序是个坏主意吗?

我可以在一个 Web 项目中有多个 web.config 文件吗?

如何将 JQuery 与母版页一起使用?

如何在 ASP.NET WebForms 中实现 TDD

IE10 SCRIPT5009:__doPostBack未定义

为什么 Asp.Net Identity IdentityDbContext 是一个黑盒?

Ef core:执行 MaxAsync 时序列不包含任何元素

对于每个请求,RestClient 应该是单例还是新的

Eval()、XPath() 和 Bind() 等数据绑定方法只能在数据绑定控件的上下文中使用

LINQ:使用 Lambda 表达式获取 CheckBoxList 的所有选定值

.NET 上的 HTTP/2(HTTP2 或 SPDY)

DBContext.Entry 有什么作用?

如何在 ASP.NET 站点中添加 favicon.ico

如何使div按钮提交其所在的表单?

为什么 Controls 集合不提供所有 IEnumerable 方法?

如何检索 X509Store 中的所有证书