gpt4 book ai didi

blazor - 属性如何导致 Blazor 中的页面更新?

转载 作者:行者123 更新时间:2023-12-05 00:43:10 26 4
gpt4 key购买 nike

我刚刚在 Blazor WebAssembly 中完成了我的第一个重要测试应用程序。 Blazor 是令人印象深刻的东西,但我发现很难推断属性更改如何导致 DOM 更新 - 例如,在 Razor 组件中引用属性的位置。

<div>@SomeProperty</div>
public int SomeProperty {get;set;}

在 WPF 中,很容易推断更改如何流动并导致呈现更改,因为它们是由事件和 DependencyProperty 更改触发的。您可以看到这些并绑定(bind)到它们。在 Blazor 中,您可以通过某种方式更改属性值并更新页面。这背后的精确机制有点像魔术。因此,很难推断如何删除复杂组件的不必要更新。

谁能解释一下这个话题的基础?

是否有任何文档或视频深入了解 Blazor 的这一领域?

最佳答案

Can anyone explain the underpinnings of this topic?

要了解更新过程,您需要了解码件。我会尽量保持简短!

所有组件都必须实现IComponentComponentBaseIComponent 的一个实现。

public interface IComponent
{
void Attach(RenderHandle renderHandle);
Task SetParametersAsync(ParameterView parameters);
}

RenderHandle 的重要部分是:

public readonly struct RenderHandle
{
public Dispatcher Dispatcher ....
//....
public void Render(RenderFragment renderFragment)
{
//....
_renderer.AddToRenderQueue(_componentId, renderFragment);
//...
}
}

而一个 RenderFragment 是:

public delegate void RenderFragment(RenderTreeBuilder builder);

Renderer 管理渲染过程。它包含表示为 RenderTree 的 DOM(由浏览器渲染的内容)。当 Renderer 将组件附加到 RenderTree 时,Renderer 会创建一个 RenderHandle 并通过调用 Attach 将其传递给组件。组件使用这个 RenderHandle 与渲染器进行通信。 Renderer 通过调用 SetParametersAsync 与组件进行通信。

通过在 RenderHandle 上调用 Render 方法并传递 RenderFragment 委托(delegate)来“渲染”组件。

这是一个简单的渲染片段:

protected RenderFragment HelloWorld => (RenderTreeBuilder builder) =>
{
builder.OpenElement(0, "div");
builder.AddContent(1, "Hello Blazor");
builder.CloseElement();
};

RenderHandle 上调用 Render 渲染组件。它只是将渲染片段放在渲染器的队列中。当渲染器运行片段时,它会检查其他组件引用的组件参数更改。它在其引用参数已更改的任何组件上调用 SetParametersAsync

StateHasChanged 是一个 ComponentBase 方法。 StateHasChanged 由 Blazor UI 事件处理程序在内部调用,因此您很少需要手动调用它。如果你这样做了,问问自己为什么?你的逻辑可能是错误的!它看起来像这样:

var task = InvokeAsync(EventMethod);
StateHasChanged();
if (!task.IsCompleted)
{
await task;
StateHasChanged();
}

主要的异常(exception)是普通的事件处理程序。如果事件更新组件中的数据,您需要通过调用 StateHasChanged 来触发手动更新。这是标准模式。

private void OnSomethingChanged(object? sender, EventArgs e)
=> this.InvokeAsync(StateHasChanged);

注意事项:

  1. StateHasChanged 具有检测渲染片段是否已排队的机制,因此它不会对多个渲染进行排队。
  2. InvokeAsync 确保任务在 UI 线程上运行。它使用 RenderHandle 上提供的 Dispatcher
  3. 当渲染器检查参数变化时,任何对象都被认为是脏的,因为渲染器没有简单的方法来检查相等性。
  4. 渲染器仅在获得线程时间时为其队列提供服务。如果您在按钮单击处理程序中运行一长串同步代码,则在同步代码完成之前不会发生任何事情。

如果您想进一步挖掘,请深入研究 ComponentBase - You can view the code here .

关于blazor - 属性如何导致 Blazor 中的页面更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70912256/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com