C# 如何绑定到使用组件标记辅助对象呈现的组件的值

C# 如何绑定到使用组件标记辅助对象呈现的组件的值,c#,data-binding,blazor,blazor-server-side,asp.net-core-tag-helpers,C#,Data Binding,Blazor,Blazor Server Side,Asp.net Core Tag Helpers,我需要在预先存在的视图和页面上使用一些定制输入作为razor组件构建,但似乎无法使用组件标记帮助器使其工作。例如,我最初使用(from)测试的组件代码导致异常,因为ValueExpression最终为null(据我所知,没有使用标记帮助器进行绑定的选项)。如果我自己设置ValueExpression,则会出现json异常(检测到对象循环)。我想可能是因为将参数从标记辅助对象移动到底层组件的机制不支持Func对象?不确定 我是否试图错误地使用标记帮助器?我在其他地方使用它来呈现自包含的组件(如整个

我需要在预先存在的视图和页面上使用一些定制输入作为razor组件构建,但似乎无法使用组件标记帮助器使其工作。例如,我最初使用(from)测试的组件代码导致异常,因为ValueExpression最终为null(据我所知,没有使用标记帮助器进行绑定的选项)。如果我自己设置ValueExpression,则会出现json异常(检测到对象循环)。我想可能是因为将参数从标记辅助对象移动到底层组件的机制不支持Func对象?不确定

我是否试图错误地使用标记帮助器?我在其他地方使用它来呈现自包含的组件(如整个EditForm),这似乎工作得很好,但如何在这个特定的用例中使其工作,我还不知道:(

在.cshtml文件中,我希望控件在其中呈现:

<component type="typeof(MyComponent)" render-mode="ServerPrerendered" param-ValueExpression="(Func<string>)(() => LocalProperty)" />

霉素

<input class="_fieldCssClasses" value="@Value" @oninput="HandleInput" />

@if (_showValidation) {
    <div class="validation-message">You must provide a name</div>
}

@code {
    private FieldIdentifier _fieldIdentifier;
    private string _fieldCssClasses => EditContext?.FieldCssClass(_fieldIdentifier) ?? "";
    private bool _showValidation = false;

    [CascadingParameter] private EditContext EditContext { get; set; }

    [Parameter] public string Value { get; set; }
    [Parameter] public EventCallback<string> ValueChanged { get; set; }
    [Parameter] public Expression<Func<string>> ValueExpression { get; set; }
    [Parameter] public bool Required { get; set; }

    protected override void OnInitialized() {
        _fieldIdentifier = FieldIdentifier.Create(ValueExpression);
    }

    private async Task HandleInput(ChangeEventArgs args) {
        await ValueChanged.InvokeAsync(args.Value.ToString());

        if (EditContext != null) {
            EditContext.NotifyFieldChanged(_fieldIdentifier);
        } else if (Required) {
            _showValidation = string.IsNullOrWhiteSpace(args.Value.ToString());
        }
    }
}

@如果(_showValidation){
您必须提供一个名称
}
@代码{
专用字段标识符_FieldIdentifier;
私有字符串_FieldCssClass=>EditContext?.FieldCssClass(_fieldIdentifier)??“”;
私有bool\u showValidation=false;
[CascadingParameter]私有EditContext EditContext{get;set;}
[参数]公共字符串值{get;set;}
[参数]公共事件回调值已更改{get;set;}
[参数]公共表达式值表达式{get;set;}
[参数]需要公共bool{get;set;}
受保护的覆盖无效OnInitialized(){
_fieldIdentifier=fieldIdentifier.Create(ValueExpression);
}
专用异步任务HandleInput(ChangeEventArgs args){
wait ValueChanged.InvokeAsync(args.Value.ToString());
if(EditContext!=null){
EditContext.NotifyFieldChanged(_fieldIdentifier);
}如果需要,请选择其他选项{
_showValidation=string.IsNullOrWhiteSpace(args.Value.ToString());
}
}
}

为了解决这个问题,我在内部组件周围创建了一个特定于用例的包装组件,确保还传入一个Id,内部组件将分配给它呈现的输入的名称和Id属性(允许它在提交表单时“绑定”),然后在页面/视图中包含包装器组件。包装器只满足内部组件的依赖关系,组件标记帮助器不会提供一种机制,以解决依赖关系是否更复杂(如Func对象)的问题

MyComponentWrapper.razor:

<div class='purdy'>
    <MyComponent Id="@Id" @bind-Value="Value"></MyComponent>
</div>
...
@code {
    [Parameter]
    public string Id { get; set; }
    [Parameter]
    public string Value { get; set; }
    ...
}

...
@代码{
[参数]
公共字符串Id{get;set;}
[参数]
公共字符串值{get;set;}
...
}
MyContainingPage.cshtml:

<component type="typeof(MyComponentWrapper)" render-mode="ServerPrerendered" param-Id="myFormInput" param-Value="LocalProperty" />
...

...