2016-08-19 48 views
1

问题

前获得先前的形式值我有一个Person对象,可以在弹出窗口中编辑。MVVM结合,节约

我需要知道,当表格被保存,如果一些值已经改变

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


代码

看看代码,它是更加明确(我已删除了不相关的代码,以便它更易于阅读):

型号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对象被绑定。

回答

1

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

现在到了一些解决方案。

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

第二种解决方案是使用form.
如果一些数据已经改变=>的形式所具有的dirtystatus巫婆,你可以启用/禁用与保存按钮,你只intressted。
因此,如果启用该按钮,则确定存在一些更改。
如果您需要知道确切的更改,您需要“克隆”您的对象,以便您可以检查出来。
但我认为,表单对象解决了当没有完成更改时无法按下按钮的问题。

希望这可以帮助你一点点。

+0

我必须知道确切的变化。我已经使用'form'绑定(参见上面的'editPersonDialog'视图代码),所以它处理一个中间对象,直到用户保存表单。但是,当viewmodel属性对象已经更新时,我需要在'savePerson'方法中进行比较。我忘了关于通过引用复制的观点(虽然我来自C#,它是相同的...),所以我会克隆我的对象。我会实现我自己的clone()方法,因为它看起来使用IClonable并不被认为是最佳实践。谢谢chillword它帮了很多;) – Yann39

+0

也许你可以在保存后更新表单对象?将这个表单作为bindingparam传递,就像这个personen是干净的,并且这些变化是在表单对象 – chillworld

+0

的确可能是一个解决方案,但是这样做我无法设法将我的对象保存到数据库,假设'newPerson'是我的绑定param,试图直接保存它('personManager.update(newPerson)')引发了一个“未知实体”异常。在保存之前将'newPerson'对象放入'person'对象('setPerson(newPerson); personManager.update(person)')会产生一个嵌套窗体异常。 – Yann39