我有一个组件MyComponentWithRenderFragments
,它呈现了一个子组件MyNestedComponentOne
。我希望孩子有一个EventCallback
,提供一些数据备份到页面,但我不知道如何将函数传递到子组件。
这是我所拥有的:
页面:
@page "/"
@using BlazorAppPlayground.Client.Components
<MyComponentWithRenderFragments
SomeDataForComponent="Hello World"
NestedComponentOneInfo='new MyNestedComponentOne(){ SomeDataForNestedOne="Testing", Callback = /* What goes here? */ }'>
<!-- -------------------------------------------------------------------------------------------------- ^^^^^^^^^^^^^^ -->
<NestedComponentOneTemplate>
<MyNestedComponentOne
SomeDataForNestedOne="@context.SomeDataForNestedOne"
Callback="@context.Callback">
</MyNestedComponentOne>
</NestedComponentOneTemplate>
</MyComponentWithRenderFragments>
<!-- This VVV works fine, and is here for reference -->
<BlazorAppPlayground.Client.Components.MyNestedComponentOne
SomeDataForNestedOne="@callbackText"
Callback="DoAThing"><!-- I know DoAThing is applicable, because it works here -->
</BlazorAppPlayground.Client.Components.MyNestedComponentOne>
@code {
private string callbackText = "Callback test";
private async Task DoAThing(string data)
{
callbackText = data;
}
}
MyComponentWithRenderFragments:
<h3>MyComponent => @SomeDataForComponent</h3>
@NestedComponentOneTemplate(NestedComponentOneInfo)
@code {
[Parameter]
public string SomeDataForComponent { get; set; } = null!;
[Parameter]
public RenderFragment<MyNestedComponentOne> NestedComponentOneTemplate { get; set; }
[Parameter]
public MyNestedComponentOne NestedComponentOneInfo { get; set; }
}
和MyNestedComponentOne:
<h3>MyNestedComponentOne => @SomeDataForNestedOne</h3>
<button @onclick="@DoAThing">Do a Thing</button>
@code {
[Parameter]
public string SomeDataForNestedOne { get; set; } = null!;
[Parameter]
public EventCallback<string> Callback { get; set; }
private async Task DoAThing()
{
await Callback.InvokeAsync("SomeDataToBePassedBack");
}
}
我不知道如何将函数传递给外部组件的NestedComponentOneInfo
属性。
注意:我知道基于这个小的例子,我可以只是使MyNestedComponentOne
MyComponentWithRenderFragments
的孩子,消除模板,这将允许我有代码类似的代码工作(下面的代码,不在Page
)。这是一组简化的组件,用于说明我所面临的问题。实际的组件要复杂得多。
提前感谢!
我不知道你想做什么,但你不能创建一个组件的实例,然后尝试将其传递给渲染过程。这就是我们要做的。
NestedComponentOneInfo='new MyNestedComponentOne(){ SomeDataForNestedOne="Testing", Callback = /* What goes here? */ }'>
下面的代码演示了如何使用DynamicComponent
和级联值。
我猜你的上下文。如果我误解了,请在你的问题中提供更多关于你想做什么的信息。
MyNestedComponentOne
<h3>MyNestedComponentOne => @SomeDataForNestedOne</h3>
<button class="btn btn-primary" @onclick="@(() => this.OnButtonClicked("Hello"))">Say Hello</button>
<button class="btn btn-secondary" @onclick="@(() => this.OnButtonClicked("Goodbye"))">Say Goodbye</button>
<button class="btn btn-info" @onclick="@(() => this.OnButtonClicked(this.SomeDataForNestedOne))">Return Provided Data</button>
@code {
[Parameter] public string SomeDataForNestedOne { get; set; } = null!;
[Parameter] public EventCallback<string> Callback { get; set; }
[CascadingParameter] private Func<string, Task>? CascadedCallback { get; set; }
private async Task OnButtonClicked(string value)
{
if (CascadedCallback is not null)
await CascadedCallback.Invoke(value);
else
await Callback.InvokeAsync(value);
}
}
MyComponentWithRenderFragments
<h3>MyComponent => @SomeDataForComponent</h3>
<DynamicComponent Type=this.ComponentType Parameters=this.ComponentInfo />
@this.ChildContent
@code {
[Parameter] public string SomeDataForComponent { get; set; } = null!;
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter] public Type? ComponentType { get; set; }
[Parameter] public Dictionary<string, object>? ComponentInfo { get; set; }
}
指数
@page "/"
@using Microsoft.AspNetCore.Components.CompilerServices
<MyComponentWithRenderFragments ComponentType=typeof(MyNestedComponentOne) ComponentInfo=this.dynamicComponentParameters />
<MyComponentWithRenderFragments ComponentType=typeof(MyNestedComponentOne) ComponentInfo="@(new() {{ "SomeDataForNestedOne", "Hello Blazor"}})">
<CascadingValue Value=this.DoAThing >
<MyNestedComponentOne SomeDataForNestedOne="Call UK" />
<MyNestedComponentOne SomeDataForNestedOne="Call France" />
<MyNestedComponentOne SomeDataForNestedOne="Call Portugal" />
</CascadingValue>
</MyComponentWithRenderFragments>
<div class="bg-dark text-white p-2 m-2">
<pre>Value = @callbackText</pre>
</div>
@code {
private string callbackText = "Callback test";
private Dictionary<string, object> dynamicComponentParameters => new()
{
{ "SomeDataForNestedOne", "Testing"},
{"Callback", EventCallback.Factory.Create<String>(this, DoAThing)}
};
private async Task DoAThing(string data)
{
await Task.Delay(100);
callbackText = data;
}
}