在C#Blazor中,如何将值从子组件(RenderFragment)传递到父页面?
我有一个Blazor项目,它加载包含razor组件的DLL。为了在客户端呈现这些动态组件,我使用render tree builder从动态组件创建一个在C#Blazor中,如何将值从子组件(RenderFragment)传递到父页面?,c#,asp.net,razor,blazor,C#,Asp.net,Razor,Blazor,我有一个Blazor项目,它加载包含razor组件的DLL。为了在客户端呈现这些动态组件,我使用render tree builder从动态组件创建一个RenderFragment,并将其放置在页面上以显示该组件。但是,在创建渲染树时,我找不到绑定值的方法。通常,我可以使用下面的父组件和子组件示例传递数据,但不确定在将动态组件转换为RenderFragment时如何传递数据 父组件 @page "/ParentComponent" <h1>Parent Comp
RenderFragment
,并将其放置在页面上以显示该组件。但是,在创建渲染树时,我找不到绑定值的方法。通常,我可以使用下面的父组件和子组件示例传递数据,但不确定在将动态组件转换为RenderFragment
时如何传递数据
父组件
@page "/ParentComponent"
<h1>Parent Component</h1>
<ChildComponent @bind-Password="_password" />
@code {
private string _password;
}
<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;
}
}
让我们先看看我是否理解你的意思。。。您需要创建一种组件渲染器,它将组件的名称作为参数,并通过IComponentService获取组件的
类型
,然后对其进行渲染。我还猜测组件的类型可能是类型Child
,您想知道如何在索引页中呈现它,并获取在子组件中输入的密码,对吗?
下面的代码描述了如何做到这一点,但我当然不能使用IComponentService服务来发现组件的类型,而是假设该类型是Child
复制并运行代码段。测试它。。。它应该有用
@page "/{ComponentName?}"
@using Microsoft.AspNetCore.Components.CompilerServices;
@if (render)
{
@dynamicComponent
}
<p>Your password: @_password</p>
@code{
private string _password;
[Parameter]
public string ComponentName { get; set; }
bool render = false;
protected override void OnInitialized()
{
render = true;
base.OnInitialized();
}
RenderFragment dynamicComponent => builder =>
{
builder.OpenComponent(0, typeof(Child));
builder.AddAttribute(1, "Password", _password);
builder.AddAttribute(2, "PasswordChanged",
EventCallback.Factory.Create<string>(this,
RuntimeHelpers.CreateInferredEventCallback(this, __value => _password = __value, _password)));
builder.CloseComponent();
};
}
@page/{ComponentName?}
@使用Microsoft.AspNetCore.Components.CompilerServices;
@如果(渲染)
{
@动态组件
}
您的密码:@\u密码
@代码{
私有字符串\u密码;
[参数]
公共字符串组件名称{get;set;}
bool render=false;
受保护的覆盖无效OnInitialized()
{
render=true;
base.OnInitialized();
}
RenderFragment dynamicComponent=>builder=>
{
OpenComponent(0,typeof(Child));
builder.AddAttribute(1,“密码”、\u密码);
builder.AddAttribute(2,“PasswordChanged”,
EventCallback.Factory.Create(此,
createInferreredEventCallback(这个,_值=>_密码=_值,_密码));
builder.CloseComponent();
};
}
注意:不应修改子组件中参数属性的值。Blazor中的参数属性是自动属性,这意味着您可以访问它们的值,但不能更改它们
此外,您不应该通过循环创建序列号。序列号应该是硬编码的。谷歌化史蒂夫·安德森(Steve Anderson)在一篇文章中讨论的这个问题。Hi@enet。你的解决方案奏效了。非常感谢。另外,如果我想绑定一个类,比如PluginData
,它有一个名为\u password
的字符串属性,我如何修改您的解决方案来实现这一点?抱歉,我不确定我是否理解您,除非您详细解释您的请求。但是,您可以将代码中可以使用的参数传递给dynamicComponent方法。您还可以在dynamicComponent方法之外定义属性并从该方法访问它们。我的意思是,不必将字符串数据从子组件传递到页面组件,是否可以将具有多个属性(如用户名、密码等)的对象从子组件传递到父组件,我将string属性与一个具有多个属性的类进行了切换。它本来应该有用的,但没用这就是为什么我请求你的帮助。我刚才再试了一次,意识到我犯了一个小错误。现在它起作用了。这样我可以绑定更多的数据。谢谢@enet.Yes,您可以传递一个对象或一组对象。。。
@page "/{ComponentName?}"
@using Microsoft.AspNetCore.Components.CompilerServices;
@if (render)
{
@dynamicComponent
}
<p>Your password: @_password</p>
@code{
private string _password;
[Parameter]
public string ComponentName { get; set; }
bool render = false;
protected override void OnInitialized()
{
render = true;
base.OnInitialized();
}
RenderFragment dynamicComponent => builder =>
{
builder.OpenComponent(0, typeof(Child));
builder.AddAttribute(1, "Password", _password);
builder.AddAttribute(2, "PasswordChanged",
EventCallback.Factory.Create<string>(this,
RuntimeHelpers.CreateInferredEventCallback(this, __value => _password = __value, _password)));
builder.CloseComponent();
};
}