You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVVM模式下仅点击保存按钮更新Observable Object的问题

解决方案:点击保存才更新ObservableObject对象

问题核心是当前UI直接绑定到原Customer对象的属性,双向绑定会实时同步UI修改到原对象,导致未保存就修改了数据。解决思路是编辑时操作原对象的副本,点击保存再将副本数据同步到原对象。

步骤1:在ViewModel中添加副本属性并创建拷贝

修改ViewModel,添加CustomerCopy作为编辑用的副本,并在原Customer赋值时创建深拷贝:

[QueryProperty(nameof(Customer), "Customer")]
public partial class CustomerDetailsEditViewModel : BaseViewModel
{
    [ObservableProperty]
    public Customer customer;

    [ObservableProperty]
    public Customer customerCopy;

    // 当原Customer对象被设置时,创建副本
    partial void OnCustomerChanged(Customer value)
    {
        if (value == null) return;
        
        // 方式1:手动复制属性(适合简单对象)
        CustomerCopy = new Customer
        {
            customerID = value.customerID,
            notes = value.notes,
            // 复制Customer类的其他所有属性
        };

        // 方式2:序列化深拷贝(适合含嵌套属性的复杂对象)
        // var json = System.Text.Json.JsonSerializer.Serialize(value);
        // CustomerCopy = System.Text.Json.JsonSerializer.Deserialize<Customer>(json);
    }

    [RelayCommand]
    public async Task EditCustomer()
    {
        // 将副本数据同步到原Customer对象
        Customer.customerID = CustomerCopy.customerID;
        Customer.notes = CustomerCopy.notes;
        // 同步其他属性

        // 执行你的更新逻辑
        // Update logic in here...
    }
}

步骤2:修改UI绑定到副本属性

将所有控件的绑定从Customer改为CustomerCopy,按钮不需要再传递参数:

<StackLayout Grid.Row="1" Orientation="Vertical" HorizontalOptions="FillAndExpand" Padding="5">
    <Frame BackgroundColor="Transparent" BorderColor="DodgerBlue" Padding="5" HorizontalOptions="FillAndExpand" CornerRadius="30" >
        <StackLayout Orientation="Horizontal" Padding="5">
            <Entry Text="{Binding CustomerCopy.customerID}" x:Name="customerIDTxt" Placeholder="رقم الهوية" PlaceholderColor="LightGray" TextColor="Black" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Margin="0,0,20,0" />
        </StackLayout>
    </Frame>
</StackLayout>

<!-- 其他控件同理,替换为CustomerCopy -->

<StackLayout Grid.Row="7" Orientation="Vertical" HorizontalOptions="FillAndExpand" Padding="5">
    <Frame BackgroundColor="Transparent" BorderColor="DodgerBlue" Padding="5" HorizontalOptions="FillAndExpand" CornerRadius="30" >
        <StackLayout Orientation="Horizontal" Padding="5">
            <Editor Text="{Binding CustomerCopy.notes}" PlaceholderColor="Black" TextColor="Black" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Margin="0,0,20,0" AutoSize="TextChanges" MaxLength="180" />
        </StackLayout>
    </Frame>
</StackLayout>

<Button Text="حفظ" HorizontalOptions="Center" WidthRequest="200" Margin="8" Style="{StaticResource ButtonOutline}" Command="{Binding EditCustomerCommand}"/>

原理说明

  • 原方式中,UI直接绑定原Customer对象,双向绑定会在UI修改时立即更新原对象属性,导致未保存就改变了数据。
  • 使用副本后,所有UI修改只会作用于CustomerCopy,原Customer保持初始状态,直到点击保存按钮,才将副本的属性同步到原对象,再执行更新逻辑。
  • 如果未点击保存就导航离开,副本会被销毁,原对象不受影响,返回页面时会重新创建新的副本,显示初始数据。

内容的提问来源于stack exchange,提问作者Mahmoud Alsheikh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:13:15