2020
上一篇写数据绑定的文章,写到最后留了一个坑。当子组件绑定父组件的一个字段,并且子组件修改它的时候父组件不能实时进行同步更新UI的问题,最近终于在Blazui作者的指导下搞定了。
UserInfo类要实现INotifyPropertyChanged接口
public class UserInfo: INotifyPropertyChanged { private string _userName; public string UserName { get { return _userName; } set { _userName = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(UserName))); } } public string Sex { get; set; } public DateTime BrithDay { get; set; } public event PropertyChangedEventHandler PropertyChanged; }没想到微软blazor还是借用了WPF搞MVVM的模式,模型需要实现INotifyPropertyChanged类,在属性发生修改的时候可以发出通知。
父组件订阅PropertyChanged事件:
@page "/"====================parent```==================<p> userName: @userInfo.UserName</p><p> sex: @userInfo.Sex</p><p> brithday: @userInfo.BrithDay</p><p> title: @title</p><InfoEdit UserInfo="userInfo" UserInfoChanged="HandleUserInfoChanged"></InfoEdit>@code { private UserInfo userInfo; private string title; protected override void OnInitialized() { userInfo = new UserInfo { UserName = "abc", Sex = "f", BrithDay = DateTime.Now }; this.userInfo.PropertyChanged += (o, e) => StateHasChanged(); base.OnInitialized(); } private void HandleUserInfoChanged(UserInfo info) { this.userInfo = info; Console.WriteLine("HandleUserInfoChanged"); }}父组件订阅子组件的PropertyChanged事件,当事件发生的时候调用组件的StateHasChanged方法。StateHasChanged方法会通知组件说状态发生变化了,也就是说组件会被重新渲染。这就是最关键的东西了。
子组件
====================child==================<p> userName: <input @bind="UserInfo.UserName" @bind:event="oninput" /></p><p> sex: <select @bind="UserInfo.Sex"> <option value="m">男</option> <option value="f">女</option> </select></p><p> BrithDay:<input @bind="UserInfo.BrithDay" /></p><button class="btn btn-danger" @onclick="InvokeChanged">保存</button>@code { [Parameter] public UserInfo UserInfo { get; set; } [Parameter] public EventCallback<UserInfo> UserInfoChanged { get; set; } private void InvokeChanged() { UserInfoChanged.InvokeAsync(this.UserInfo); Console.WriteLine("InvokeChanged"); }}运行

一些吐槽
虽然搞定了子父组件同步的问题,但是我不能理解的是,为什么微软要搞的这么复杂。使用@bind-UserInfo会强制用户在子组件实现一个 EventCallback
No comments:
Post a Comment