提问人:LWC433 提问时间:7/9/2021 更新时间:7/12/2021 访问量:2191
Blazor 组件:如何从孙子到子项到父项或孙子项到父项进行通信
Blazor components: How to communicate from grandchild to child to parent or grandchild to parent
问:
在我的 Blazor Server 应用中,我有一个名为“主页”的页面,它基本上是一个搜索页面。在主页(“父”)上,有一个窗体,其中包含用于筛选存储在后端数据库中的数据的控件。搜索结果的每一行都有一个“编辑”按钮,该按钮显示一个引导对话框,允许编辑数据。单击 UpdateDocumentNumber(孙子)组件上的“保存”按钮后,我想刷新主页(父)中的搜索结果。
- 父级:带有搜索结果网格的主页(页面);为每个项目嵌入一个 DisplayDocumentNumber 组件
- 子组件:DisplayDocumentNumber 组件,该组件有自己的(子)UpdateDocumentNumber 组件
- 孙子:UpdateDocumentNumber 组件 - 引导对话框
我的理解是,我可以使用事件回调来做到这一点;但是,虽然我可以从孙子到子孙提出/调用事件回调,但我似乎无法从孩子通知父项。
更多细节...
当“主页”(“父”页)循环访问返回的项列表时,它会插入一个组件(“子”),然后该组件具有一个组件来引用“编辑”对话框。下面是循环访问搜索结果的主页:<DisplayDocumentNumber>
<DisplayDocumentNumber>
<tbody>
@foreach (var documentNumber in DocumentNumbers)
{
<DisplayDocumentNumber DocumentNumber="documentNumber" /> // DocumentNumber parameter in DisplayDocumentNumber receives the data from the documentNumber local var
}
</tbody>
下面是 DisplayDocumentNumber 组件:
public partial class DisplayDocumentNumber : ComponentBase
{
[Parameter]
public DocumentNumberDto DocumentNumber { get; set; }
[Parameter]
public EventCallback<bool> OnDocumentNumberUpdatedEventCallback { get; set; }
}
请注意 .这在孙子和孩子之间都能正常工作。public EventCallback<bool> OnDocumentNumberUpdatedEventCallback { get; set; }
在 DisplayDocumentNumber.razor 组件中,是为搜索结果中的每个文档编号呈现的行,包括一个“编辑”按钮,该按钮具有用于显示启动对话框的 DOM 事件。最后,如上所述,还有组件,即<UpdateDocumentNumberDialog>
<tr>
<td>@DocumentNumber.Column1Name</td>
<td>@DocumentNumber.Column2Name</td>
...etc
<td><button class="btn btn-primary table-btn" @onclick="@(() => ShowEditDocumentNumberDialog(DocumentNumber))">Edit</button></td>
<UpdateDocumentNumberDialog @ref="UpdateDocNumDialog" DocumentNumberForUpdating="DocumentNumber" DocumentNumberUpdatedEventCallback="@UpdateDocumentNumberDialog_OnDialogClose"></UpdateDocumentNumberDialog>
</tr>
如果事件回调只适用于孙子到子项或子项到父项,我是否必须创建某种状态容器,如 Chris Sainty (https://chrissainty.com/3-ways-to-communicate-between-components-in-blazor/) 所描述的那样?或者,我是否遗漏了有关事件回调的内容?我试图消除子组件,但失败了,因为“编辑”按钮总是显示网格中迭代的最后一项。
答:
我能想到几个选择。一种是让孙子访问主页。这根本不需要事件:
家长.razor
<CascadingValue Value="this">
Body of page, somewhere in there including <Grandchild/>
</CascadingValue>
@code{
async Task DoSomething(){
}
}
孙子剃须刀
@code {
[CascadingParameter]
public Parent MainPage {get; set;} // Or whatever your main page is called
async Task StartSomething (){
if (MainPage is not null) MainPage.DoSomething();
}
}
评论
我在 Child 和 Grandchild 组件中包含以下参数:
[Parameter]
public Action MyDataHasChanged {get;set;}
此外,在我的孙子组件中:
@code
{
public void RefreshMySearchResultsInParent()
{
MyDataHasChanged?.Invoke();
}
}
在我的子组件中:
<Grandchild @MyDataHasChanged="MyDataHasChanged"></Grandhild>
在我的父组件中:
<Child @MyDataHasChanged="RefreshMySearchResults"></Child>
@code
{
public void RefreshMySearchResults()
{
//Do this...
}
}
评论
CascadingValues
正是这样,级联。您可以在父组件上定义回调(例如; ),并将父组件向下级联到孙组件,其中孙组件可以在父组件上调用回调。OnDocumentNumberUpdatedEventCallback
<CascadingValue Value="this">
Value="this"
Value="this"