在Blazor中,组件示例可以在重新渲染时重用。例如,以下页面组件示例在id
url路径参数更改时(通过单击链接或通过编程导航或使用浏览器后退按钮)被重用,而无需重新初始化:
@page "/data/{id:int}"
<h1>Data of @Id</h1>
<p>Data: @_data</p>
<p><NavLink href="@("data/"+(Id+1))">Next</NavLink></p>
@code {
[Parameter]
public int Id { get; set; }
private int? _currentlyLoadedId;
private string _data = "";
protected override async Task OnParametersSetAsync()
{
// This check seems hacky...
if (Id != _currentlyLoadedId)
{
// The parameter must have been changed.
_data = await LoadAndSetData(Id);
_currentlyLoadedId = Id;
}
}
private async Task<string> LoadAndSetData(int id)
{
// Simulate a server request
await Task.Delay(2000);
return "Demo data for ID " + id;
}
}
字符串
对于这样一个看似常见的问题,这种方法似乎有点冗长/笨拙。将离散的命令式逻辑(如加载数据)绑定到渲染周期似乎是根本错误的方法...
没有内置的方法来评估id
参数是否在不同的渲染周期之间真正改变了。而且,OnParametersSetAsync
方法被调用的次数没有限制,因为可能有许多渲染通道每个都有相同的参数(由于我的组件或潜在的父组件中的其他逻辑)。
是否有另一种/更好的方法来实现相同的行为?一种不将决策逻辑与呈现逻辑绑定在一起的方法?
1条答案
按热度按时间xxhby3vn1#
组件没有被重用:没有页面更改(页面是一个组件),所以渲染器没有理由修改渲染树。你所拥有的只是参数更改,所以只有
OnParametersSet{Async}
被调用。是的,你的逻辑是正确的。这就是
ComponentBase
的方法。只有当值发生变化时才获取数据。你还想把“加载数据的逻辑”绑定到什么地方?
OnParametersSetAsync
方法被调用的次数没有限制正确,如果参数是引用对象,则非常正确。但问题是什么呢?请参阅我对最近一个问题的回答。https://stackoverflow.com/a/77676270/13065781
附加注解。
你所展示的代码没有任何问题。我可以向你展示我的一些项目中的类似代码。你会看到世界各地都在使用相同的基本结构来解决这个问题。还有其他方法,比如编写一个自定义基本组件来处理这种情况,但更好?不同,但不一定更好。
我不是一个可观察事物的爱好者,我不使用它们。其他人可能会告诉你如何优雅地使用它们。
我个人是如何做到这一点的?组件只包含呈现逻辑。数据(如记录或集合)存在于表示层服务中。我通常使用模式对话框来显示记录,或使用组件的 Jmeter 板集合来处理复杂的聚合对象。
你在这里看到的看起来像一个页面,通过下一个和上一个按钮滚动记录。在这种情况下,按钮正常启动记录更改。
如果您担心性能问题,请参阅此链接以了解有关优化组件的更多背景知识:
https://learn.microsoft.com/en-us/aspnet/core/blazor/performance?view=aspnetcore-8.0#implement-setparametersasync-manually