Blazor WASM嵌套双向绑定问题:自定义组件绑定对象属性失败
Blazor WASM嵌套双向绑定问题解决
问题根源
- 单向绑定无法回传数据:当前
FormSection中使用TextValue="@Forecast.Date"是单向数据传递,仅将Forecast的初始值传给输入组件,输入组件的修改无法反向更新Forecast对象,导致点击保存时模型无变化。 - 自定义组件未遵循双向绑定约定:Blazor的
@bind-XXX语法要求组件必须同时定义XXX参数和对应的XXXChanged回调事件。你的输入组件只有TextValue参数,缺少TextValueChanged回调,因此使用@bind-TextValue时会报错。
解决方案
步骤1:修改自定义输入组件,添加双向绑定回调
为每个输入组件补充TextValueChanged回调参数,并确保值变化时触发回调:
InputDateCustom
<input class="form-control form-control-sm" type="date" @bind-value="TextValue" @bind-value:after="OnTextValueChanged" /> @code { [Parameter] public DateTime TextValue { get; set; } = DateTime.Now; // 双向绑定必须的回调参数 [Parameter] public EventCallback<DateTime> TextValueChanged { get; set; } private async Task OnTextValueChanged(DateTime newValue) { await TextValueChanged.InvokeAsync(newValue); } }
InputTextCustom
<input class="form-control form-control-sm" type="text" @bind-value="TextValue" @bind-value:after="OnTextValueChanged" /> @code { [Parameter] public string TextValue { get; set; } = string.Empty; [Parameter] public EventCallback<string> TextValueChanged { get; set; } private async Task OnTextValueChanged(string newValue) { await TextValueChanged.InvokeAsync(newValue); } }
InputNumberCustom
<input class="form-control form-control-sm" type="number" @bind-value="TextValue" @bind-value:after="OnTextValueChanged" /> @code { [Parameter] public int TextValue { get; set; } = 0; [Parameter] public EventCallback<int> TextValueChanged { get; set; } private async Task OnTextValueChanged(int newValue) { await TextValueChanged.InvokeAsync(newValue); } }
步骤2:修改FormSection组件,使用双向绑定传递属性
将FormSection中的单向绑定改为双向绑定,确保输入组件的修改能同步到Forecast对象:
<div> <label for="datetime" class="form-label">Date</label> <InputDateCustom @bind-TextValue="Forecast.Date" /> </div> <div> <label for="temperature" class="form-label">Temperature</label> <InputNumberCustom @bind-TextValue="Forecast.TemperatureC" /> </div> <div> <label for="summary" class="form-label">Summary</label> <InputTextCustom @bind-TextValue="Forecast.Summary" /> </div> @code { [Parameter] public WeatherForecast Forecast { get; set; } }
步骤3:验证Index页面的模型状态
确保Index页面中forecast是可变实例(而非只读),SaveData方法能正确读取更新后的值:
<div class="d-flex flex-column gap-3"> <FormSection Forecast=@forecast /> <button class="btn btn-sm btn-success" @onclick=SaveData>Save data</button> </div> @code { private WeatherForecast forecast = new WeatherForecast(); private void SaveData() { // 此处可获取更新后的forecast数据 Console.WriteLine($"Date: {forecast.Date}, Temp: {forecast.TemperatureC}, Summary: {forecast.Summary}"); } }
最佳实践
- 遵循Blazor双向绑定约定:自定义输入组件尽量使用
Value作为参数名,对应ValueChanged回调,和Blazor内置输入组件(如InputText)保持一致,提升代码可读性和通用性。 - 优先使用内置绑定语法:使用
@bind-XXX而非手动处理@onchange事件,减少重复代码,避免手动解析值的错误。 - 组件职责单一化:
FormSection专注于表单布局和组件分发,输入组件专注于输入逻辑和双向绑定,便于维护和复用。
内容的提问来源于stack exchange,提问作者Mirko Putignani
相关产品推荐
相关产品推荐

