I have a Blazor project that loads DLL that contain razor components. To render these dynamic components at client-side, I use render tree builder to create a RenderFragment
from dynamic component and place it on the page to show the component. However, I can't find a way to bind a value while creating the render tree. Normally, I can pass data using the example below of parent and child component, but not sure how to do it when converting dynamic components to RenderFragment
.
Parent component
@page "/ParentComponent"
<h1>Parent Component</h1>
<ChildComponent @bind-Password="_password" />
@code {
private string _password;
}
Child component
<h1>Child Component</h1>
Password:
<input @oninput="OnPasswordChanged"
required
type="@(_showPassword ? "text" : "password")"
value="@Password" />
<button class="btn btn-primary" @onclick="ToggleShowPassword">
Show password
</button>
@code {
private bool _showPassword;
[Parameter]
public string Password { get; set; }
[Parameter]
public EventCallback<string> PasswordChanged { get; set; }
private Task OnPasswordChanged(ChangeEventArgs e)
{
Password = e.Value.ToString();
return PasswordChanged.InvokeAsync(Password);
}
private void ToggleShowPassword()
{
_showPassword = !_showPassword;
}
}
Dynamic Component to RenderFragment
The code below shows how I am able to show the component on the page by converting it to RenderFragment
. Do you know how I can bind a variable at the render tree builder, to pass data from dynamic component to the parent page?
Note: This Dynamic Component @dynamicComponent
is same as the Child component above and I want the password data from it.
@page "/{ComponentName}"
@inject IComponentService ComponentService
@if (render)
{
@dynamicComponent()
@_password;
}
@code{
private string _password;
[Parameter]
public string ComponentName { get; set; }
bool render = false;
protected override void OnInitialized()
{
render = true;
base.OnInitialized();
}
RenderFragment dynamicComponent() => builder =>
{
RazorComponentModel component = ComponentService.GetComponentByPage(ComponentName);
builder.OpenComponent(0, component.Component);
for (int i = 0; i < component.Parameters.Count; i++)
{
var attribute = component.Parameters.ElementAt(i);
builder.AddAttribute(i + 1, attribute.Key, attribute.Value);
}
builder.CloseComponent();
};
}