2020-06-11-ASP.NET Core Blazor 子组件父组件数据同步的问题
上一篇写数据绑定的文章,写到最后留了一个坑。当子组件绑定父组件的一个字段,并且子组件修改它的时候父组件不能实时进行同步更新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
关注我的公众号一起玩转技术

       
QQ群:1022985150 VX:kklldog 一起探讨学习.NET技术
作者:Agile.Zhou(kklldog)            
 
出处:http://www.cnblogs.com/kklldog/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号