I have a need to use some custom inputs built as razor components on pre-existing views and pages, but can't seem to get it to work using the component tag helper. For example, the component code that I've been testing with (from https://chrissainty.com/creating-bespoke-input-components-for-blazor-from-scratch/) at first results in an exception because ValueExpression ends up being null (no options for binding using the tag helper, from what I can tell). If I then set ValueExpression myself, I end up with a json exception (object cycle detected). I think maybe because the mechanism for moving parameters from the tag helper to the underlying component doesn't support Func<> objects? Not sure.
Am I trying to use the tag helper incorrectly perhaps? I'm using it in other places to render self-contained components (like an entire EditForm), and that seems to be working fine, but how to get it working in this particular use case eludes me :(
Inside .cshtml file I want the control to render in:
<component type="typeof(MyComponent)" render-mode="ServerPrerendered" param-ValueExpression="(Func<string>)(() => LocalProperty)" />
MyComponent.razor
<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());
}
}
}