MVVM 绑定,在保存之前获取以前的表单值

MVVM binding, get previous form values before saving

问题

我有一个 Person 对象,可以在弹出窗口中编辑 window。

我需要知道,当 表单被保存时 ,如果某些 值已经改变

我正在使用 全局变量 来存储对象的 初始状态 但变量似乎是 也更新了,我不明白为什么。


代码

看一下代码,它更明确(我删除了不相关的代码,这样更容易阅读):

型号 (Person.java) :

@Entity
@Table(name = "person")
public class Person {

    @Column
    private String lastName;

    @Column
    private String firstName;

}

查看模型 (PersonVm.java) :

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class PersonVm {

    private Person person;
    private static Person initialPerson;
    private PersonGroupingVm personGroupingModel;

    @Init
    public void init(@ExecutionArgParam("person") Person pers, @ContextParam(ContextType.VIEW) Component view) {
        Selectors.wireComponents(view, this, false);
        if (pers != null) 
            person = pers;
        setPersonGroupingModel(new PersonGroupingVm(personMgr.getPersons(), new PersonComparator(), false));
    }

    @Command
    @NotifyChange("person")
    public void openEditPersonDialog(@BindingParam("person") Person pers) {
        initialPerson = pers;
        Map<String, Object> args = new HashMap<String, Object>();
        args.put("person", pers);
        Executions.createComponents(".../editPerson.zul", null, args);
    }

    @Command
    @NotifyChange("person")
    public void savePerson() {
        Clients.alert(person.equals(initialPerson) + "");
        Clients.alert(person.getFirstName());
        Clients.alert(initialPerson.getFirstName());
        // person and initialPerson both contain new values !
    }

}

查看 (persons.zul) :

<vlayout apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('ch.myorg.vm.PersonVm')">
    <grid model="@load(vmp.personGroupingModel)">
        ...
        <template name="model" var="pers">
            <row>
                <label value="@load(pers.firstName)"/>
                <label value="@load(pers.lastName)"/>
                <button onClick="@command('openEditPersonDialog', person=pers)"/>
            </row>
        </template>
    </grid>
</vlayout>

查看 (editPersonDialog.zul) :

<window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('ch.myorg.vm.PersonVm')">
    <div form="@id('p') @load(vm.person) @save(vm.person, before='savePerson')">
        <textbox value="@bind(p.firstName)"/>
        <textbox value="@bind(p.lastName)"/>
        <button label="${labels.action.validate}" onClick="@command('savePerson')"/>
    </div>
</window>

为什么我的 2 个对象(personinitialPerson)包含新值?仅绑定 person 对象。

快速回答:Java 通过引用威胁对象,这意味着 2 个变量指向相同的内存位置。

现在有一些解决方案。

第一个解决方案是从数据库中获取一个新对象作为原始对象。
但是,如果你这样做 => 这应该是服务器而不是 GUI 部分的更多代码。

第二种解决方案是使用 form.
仅当某些数据已更改时,您才会感到困惑 => 表单具有脏状态 您可以 enable/disable 使用保存按钮。
因此,如果启用了该按钮,您确定会有一些变化。
如果您需要知道确切的更改,您需要 "clone" 您的对象,以便您可以查看它。
但我认为表单对象解决了你在没有完成任何更改时无法按下按钮的问题。

希望对您有所帮助。