2016-08-19 95 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