Blazor-SetParameters-为什么字符串参数绑定的行为与复杂类型不同



考虑具有字符串参数和复杂类型参数的子组件。

<Child Name="@strProperty" />
<Child Model="@compelexType" />

假设两个参数都没有更改,那么在父组件上调用StateHasChanged会导致具有复杂参数的Child组件重新应答,但不会使用字符串参数。

请参阅此演示:https://blazorrepl.com/repl/wbYguGuA515uMYR742

你如何解释不同的行为?

这本身不是一个答案,我只是需要比注释中更多的空间。

我不相信引用的文件完全解释了观察到的结果。

文档说明:

默认情况下,Razor组件继承自ComponentBase基类,该基类包含在以下时间触发重新渲染的逻辑:

  1. 从父组件应用更新的参数集之后
  2. 为级联参数应用更新的值之后
  3. 在通知事件并调用其自己的事件处理程序之后
  4. 在调用其自己的StateHasChanged方法之后(请参阅ASP.NET Core Razor组件生命周期(

这些都是内部操作。前两个发生在对组件调用SetParametersAsync之后。最后两个来自组件内部的操作。

任何子组件活动(如重新渲染(都是由调用SetParametersAsyncRenderer触发的,而不是由父组件直接触发的。CCD_ 4基于检测到的对任何子组件CCD_。因此,发生重新渲染的原因是Renderer决定它是一个对象而不是基元类型,与ComponentBase无关。

为了证明这一点,我基于IComponent而不是ComponentBase编写了一个非常基本的组件。它看起来像这样:

using Blazor.Starter.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using System.Threading.Tasks;
namespace Blazor.Starter.Components.TestComponents
{
public class ObjectTest : IComponent
{
[Parameter] public DataModel Model { get; set; }
[Parameter] public int Value { get; set; }
private RenderHandle _renderHandle;
private int _renders;
public void Attach(RenderHandle renderHandle)
{
_renderHandle = renderHandle;
}
public Task SetParametersAsync(ParameterView parameters)
{
parameters.SetParameterProperties(this);
_renders++;
this.Render();
return Task.CompletedTask;
}
public void Render()
=> _renderHandle.Render(RenderComponent);
private void RenderComponent(RenderTreeBuilder builder)
{
builder.OpenElement(0, "div");
builder.AddContent(1, $"Rendered {_renders}");
builder.CloseElement();
}
}
}

如果在调用父级SetParametersAsync时设置Model,如果仅设置Value,则不会。同样的结果。

文档:

如果以下任一项为真,则从ComponentBase继承的组件会由于参数更新而跳过转发器:

  • 所有参数值都是已知的不可变的基元类型,如intstringDateTime自上一组参数设置以来没有更改
  • 组件的ShouldRender方法返回false

正如@GSerg在评论中所说:这是因为基元属性没有更改,所以它不会更新。

最新更新