我正在尝试使用。net 6中的DynamicComponent在Blazor Wasm中呈现动态内容。要呈现的组件在JSON文件中定义,结构如下:
{
"type":"MyButton",
"parameters": {
"Label":"My Buttom",
"OnClicked": "DoAction"
}
}
DynamicComponent允许我们使用Dictionary<string,>就像下面的代码一样,我们可以定义组件。参数为Dictionary<string,object>
<DynamicComponent Type=@component.type Parameters=@component.parameters />
在我的razor文件中,我已经定义了DoAction()"方法。我希望在点击MyButton组件时调用这个方法。但是我们如何将这个DoAction()方法作为EventCallBack传递给渲染的组件呢?色。剃须刀组件:
<button class="btn btn-primary" @onclick="HandledClicked">@LabelText</button>
@code{
[Parameter]
public string LabelText {get; set;}
[Parameter]
public EventCallback OnClicked { get; set; }
private void HandleClicked()
{
OnClicked.InvokeAsync();
}
}
DynamicPage。剃刀:(更新#1)
@page "/DynamicPage"
@foreach (var component in components)
{
<DynamicComponent Type="component.Type" Parameters="component.Parameters" />
}
@code{
List<JsonComponent> components = new();
protected async override Task OnInitializedAsync()
{
var jsonComponentList = await Http.GetFromJsonAsync<List<JsonComponent>>("/data.json");
foreach (var item in jsonComponentList)
{
JsonComponent componentItem = new();
componentItem.Type = Type.GetType($"{nameSpaceComponents}{item.Type}");
componentItem.Parameters = new();
// below code to populate the component parameters as Dictionary<string, object>.
// the problem here is how to pass "DoAction()" method which is defined in the
// Json file to the rendered component by adding it to the paramater Dictionary<string, object>?
foreach (var kvp in item.Parameters)
{
var jsonElement = ((JsonElement)kvp.Value).GetString();
componentItem.Parameters.Add(kvp.Key, jsonElement);
}
}
}
public void DoAction()
{
//.. codes to perform some custom logic here when Button component is clicked.
}
}
JsonComponent.cs类:
public class JsonComponent
{
public JsonComponent()
{
}
public Type Type { get; set; }
public Dictionary<string, object> Parameters { get; set; }
}
为了在运行时通过Dictionary<string将方法或函数传递给动态生成的组件,object>参数,我们需要使用EventCallback.Factory.Create()
方法创建一个EventCallBack。
我使用foreach
循环来获取Json文件中定义的参数列表,我们需要将其添加到Dictionary<string,>参数。
然后我有一个if
条件来检查要传递给组件的参数是否是一个事件。在这里,我预定义的所有事件键名称应该前缀"On"。onclick。如果参数是Event,那么我们创建一个EventCallback
callback = EventCallBack.Factory.Create<string>(this, (Action<string>) this.GetType().GetMethod(kvp.Value.ToString()).CreateDelegate(typeof(Action<string>), this));
componentItem.Parameters.Add(kvp.Key, callback);
下面是DynamicPage.razor的代码:
@page "/DynamicPage"
@foreach (var component in components)
{
<DynamicComponent Type="component.Type" Parameters="component.Parameters" />
}
@code{
List<JsonComponent> components = new();
EventCallBack<string> callback; // Declare a EventCallBack variable use to pass to the generated Component
protected async override Task OnInitializedAsync()
{
var jsonComponentList = await Http.GetFromJsonAsync<List<JsonComponent>>("/data.json");
foreach (var item in jsonComponentList)
{
JsonComponent componentItem = new();
componentItem.Type = Type.GetType($"{nameSpaceComponents}{item.Type}");
componentItem.Parameters = new();
foreach (var kvp in item.Parameters)
{
var jsonElement = ((JsonElement)kvp.Value).GetString();
if (kvp.Key.ToString().StartsWith("On"))
{
callback = EventCallBack.Factory.Create<string>(this, (Action<string>) this.GetType().GetMethod(kvp.Value.ToString()).CreateDelegate(typeof(Action<string>), this));
componentItem.Parameters.Add(kvp.Key, callback);
}
else
{
componentItem.Parameters.Add(kvp.Key, jsonElement);
}
}
components.Add(componentItem);
}
}
}