2017-07-26 97 views
0

我试图了解ZKoss如何在使用MVVM模式的情况下工作。在MVVM中未触发ZK Combobox事件

我使用JDK8 ZK8.0.2.2 CE和wildfly 10

我有一个组合框和一个网格。我希望组合框onSelect事件触发网格更新。网格用组合框中选定的项目作为参数进行更新。

问题是,应该由onSelect调用的@Command方法永远不会被调用,并且永远不会触发更新。

另一件事:如果我得到了数据绑定的正确工作方式,则Combobox上的onSelect参数甚至不是必需的。 Grid通过参数model =“@ load(vm.allMedia)”绑定到ViewModel(allMedia)中的ListModel。

因此,如果所有媒体更改,网格应自动更新(类似于JavaFX中发生的绑定属性)。显然这没有发生。

这是.zul文件:

<?xml version="1.0" encoding="UTF-8"?> 
<zk xmlns="http://www.zkoss.org/2005/zul"> 
    <window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('mediadb.gui.MediaViewModel')"> 
     <vbox pack="center" align="top" width="990px" height="600px"> 
      <panel title="Search" border="normal" vflex="true"> 
       <panelchildren> 
        <label value="Type" class="boxlabel" /> 
        <combobox id="cmbType" width="150px" model="@load(vm.allType)" selectedItem="@bind(vm.actualType)" 
         onSelect="@Command('updateTable')"> 
         <template name="model"> 
          <comboitem label="@load(each.label)" /> 
         </template> 
        </combobox> 
       </panelchildren> 
      </panel> 
      <panel title="Media" border="normal" vflex="true"> 
       <panelchildren> 
        <grid id="mediaGrid" mold="paging" autopaging="true" 
          emptyMessage="No results" pagingPosition="both" 
          vflex="true" model="@load(vm.allMedia)"> 
         <columns sizable="true"> 
          <column hflex="1" label="ID" align="center" sort="auto(id)" /> 
          <column hflex="3" label="Serial#" align="center" sort="auto(serialNumber)" /> 
          <column hflex="3" label="Support Label" align="center" sort="auto(supportLabel)" /> 
          <column hflex="3" label="User Label" align="center" sort="auto(userLabel)" /> 
          <column hflex="2" label="Added" align="center" sort="auto(addDate)" /> 
         </columns> 
         <template name="model"> 
          <row vflex="1"> 
           <label value="@load(each.id)" /> 
           <label value="@load(each.serialNumber)" /> 
           <label value="@load(each.supportLabel)" /> 
           <label value="@load(each.userLabel)" /> 
           <label value="@load(each.addDate) @converter('formatedDate', format='dd/MM/yyyy')" /> 
          </row> 
         </template> 
        </grid> 
       </panelchildren> 
      </panel> 
     </vbox> 
    </window> 
</zk> 

,这是模型视图:

package mediadb.gui; 

import mediadb.db.DataProvider; 
import mediadb.entity.MdbCategory; 
import mediadb.entity.MdbMedia; 
import java.beans.PropertyVetoException; 
import java.io.IOException; 
import java.sql.SQLException; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import org.zkoss.bind.annotation.Command; 
import org.zkoss.bind.annotation.Init; 
import org.zkoss.bind.annotation.NotifyChange; 
import org.zkoss.zul.ListModel; 
import org.zkoss.zul.ListModelList; 

public class MediaViewModel { 

    private DataProvider db = null; 
    private ListModel<MdbCategory> allType = null; 
    private ArrayList<MdbMedia> allMediaData = null; 
    private ListModel<MdbMedia> allMedia = null; 
    private MdbCategory actualType = null; 

    @Init 
    public void init() { 
     try { 
      db = DataProvider.getInstance(); 
      allType = new ListModelList<>(db.getCategories()); 
      actualType = allType.getElementAt(0); 

      allMediaData = new ArrayList(); 
      allMedia = new ListModelList<>(allMediaData); 

     } catch (IOException | SQLException | PropertyVetoException e) { 
      Logger.getLogger(MediaViewModel.class.getName()).log(Level.SEVERE, null, e); 
     } 
    } 

    @Command 
    public void updateTable() { 
     allMediaData.clear(); 
     allMediaData.addAll(db.getMedia(actualType.getLabel())); 
    } 

    public ListModel<MdbCategory> getAllType() { 
     return allType; 
    } 

    public void setAllType(ListModel<MdbCategory> allType) { 
     this.allType = allType; 
    } 

    public MdbCategory getActualType() { 
     return actualType; 
    } 

    public void setActualType(MdbCategory actualType) { 
     this.actualType = actualType; 
    } 

    public ListModel<MdbMedia> getAllMedia() { 
     return allMedia; 
    } 
} 

(我省略数据bean,这是问题的跑题DB访问。 )

我做错了吗?有没有更好的方法来做到这一点?

在此先感谢。

回答

1

@Command在你的代码中有一个大写的C字母改为@command,它应该工作正常。

改变成:

<combobox id="cmbType" width="150px" model="@load(vm.allType)" 
    selectedItem="@bind(vm.actualType)" onSelect="@command('updateTable')"> 

不要忘记你的updateTable方法

@Command 
@NotifyChange({"allMediaData","allMedia"}) 
public void updateTable() { 
    allMediaData.clear(); 
    allMediaData.addAll(db.getMedia(actualType.getLabel())); 
    allMedia.AddAll(allMediaData); 
} 
+0

都能跟得上添加@NotifyChange("allMediaData"),它仍然无法正常工作。我按照你的建议改变了论据(我不知道它们区分大小写),但它的行为完全一样。 – NoWone

+0

感谢您的努力,仍然没有运气。我已经尝试过,实际上(即使它不应该是必要的,因为当Grid阅读时绑定到allMedia对象 - 如果我理解正确)。 – NoWone

+0

@NoWone你有没有尝试将所有数据添加到AllMedia updateTable方法?尝试更新我的新答案 –