blazor - 在泛型 Blazor 子控件中调用方法
问题描述
在通用子控件中调用方法
我有一个名为 InfoPanel 的容器控件,它应该包含各种类型的其他控件的实例,但都派生自一个名为 InfoPanelControl 的基类。InfoPanelControl 定义了一个虚拟方法 Save。
我想从 InfoPanel 中调用包含控件的 Save 方法,以便每个具体控件都进行自己的特定保存。
这是它的外观:
<InfoPanel>
<Budget />
</InfoPanel>
这里的预算来自 InfoPanelControl。
InfoPanel 有一个 ChildControl 属性:
[Parameter] private RenderFragment ChildContent { get; set; }
其中填充了子控件的实例,在此示例中为预算。
现在,我需要从 InfoPanel 访问 Budget 控件(作为 InfoPanelControl,因为我不需要特定类型,只需要基本类型)。在 InfoPanel 中,我希望执行以下操作:
InfoPanelControl childControl = ChildContent.Target as InfoPanelControl;
但是,ChildContent.Target 返回的不是投射到 InfoPanelControl 的预算。它实际上是一个更高级别控件的实例,它是 InfoPanel 的容器。
如何从 InfoPanel 访问 Budget (casted to InfoPanelControl) 控件的方法?
解决方案
奇怪的是,几天前我实际上做了类似的事情。我最终使用级联参数/值来解决我的特定问题。我在下面使用了一个简单的示例来展示一般逻辑。
我希望将来会有更好的解决方案,但在撰写本文时,blazor 仍处于预览阶段。
我还建议使用 ChildControlBase 来实现所有子控件继承的接口。
这个实现的另一个“好处”是它适用于可能在“ChildContent”中的多个子组件,并且它周围的标记无关紧要。
我目前在 OnParametersSet 的覆盖中将子级添加到父级。根据您的需要,您可能希望以不同的方式使用它或具有其他逻辑。
ParentControlBase.cs
public class ParentControlBase : ComponentBase
{
private List<IDoSomething> _childControls;
public ParentControlBase()
{
_childControls = new List<IDoSomething>();
}
public void AddChildControl(IDoSomething control)
{
if (!_childControls.Contains(control))
{
_childControls.Add(control);
}
}
public void DoSomethingOnRelevantChildControls()
{
foreach (var control in _childControls)
{
control.DoSomething();
}
}
}
ParentControl.razor
@inherits ParentControlBase
<div class="parent-control-container">
<div>Parent Control</div>
<CascadingValue Name="IDoSomethingParentControl" value="@this">
@ChildContent
</CascadingValue>
<div class="btn btn-primary" @onclick="@DoSomethingOnRelevantChildControls">Do Something</div>
</div>
@code{
[Parameter]
private RenderFragment ChildContent { get; set; }
}
通用子控件实现
public interface IDoSomething
{
void DoSomething();
}
子控件
@implements IDoSomething
<div>ChildControl</div>
@code
{
[CascadingParameter(Name = "IDoSomethingParentControl")]
private ParentControlBase CurrentParentControl { get; set; }
protected override void OnParametersSet()
{
if (CurrentParentControl != null)
{
CurrentParentControl.AddChildControl(this);
}
}
public void DoSomething()
{
//Do Something implementation
}
}
推荐阅读
- r - 投资组合构建 - 因子模型
- java - Spring Cloud Gateway 和 CORS 标头
- laravel - array_merge():期望参数 2 是一个数组,给定推送器 laravel 为 null
- javascript - Python:使用 Beautifulsoup 设置 JavaScript 变量?
- git - 语义版本控制,用 2 个字节标识提交
- python - 在一个变量中将4位整数除以2作为python中的元组
- c# - 如何使用按钮在图表上获取昨天的日期?
- memory - TensorRT:如何计算 TensorRT 优化模型(model.trt)中的 FLOPS 数?
- next.js - 带有 getInitialProps 和 getStaticProps 的页面
- html - 在同一页面上使用不同版本的 Bootstrap css