ZK Combobox 事件未在 MVVM 中触发
ZK Combobox event not triggering in MVVM
我正在尝试了解 ZKoss 的工作原理,特别是使用 MVVM 模式。
我在 JDK8 和 wildfly 10 上使用 ZK8.0.2.2 CE。
我有一个组合框和一个网格。我希望组合框 onSelect 事件触发网格更新。使用组合框中的所选项目作为参数更新网格。
问题是,应该由 onSelect 调用的 @Command 方法从未被调用,也从未触发更新。
还有一件事:如果我了解数据绑定的工作原理,那么 Combobox 上的 onSelect 参数甚至都不是必需的。 Grid 通过参数 model="@load(vm.allMedia)"
绑定到 ViewModel (allMedia) 中的 ListModel
因此,如果 allMedia 发生变化,网格应该自动更新(类似于在具有绑定属性的 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 和数据库访问。)
我做错了吗?有更好的方法吗?
提前致谢。
@Command
在您的代码中有一个大写的 C 字母将其更改为 @command
并且它应该可以正常工作。
改成:
<combobox id="cmbType" width="150px" model="@load(vm.allType)"
selectedItem="@bind(vm.actualType)" onSelect="@command('updateTable')">
并且不要忘记在您的 updateTable 方法中添加 @NotifyChange("allMediaData")
@Command
@NotifyChange({"allMediaData","allMedia"})
public void updateTable() {
allMediaData.clear();
allMediaData.addAll(db.getMedia(actualType.getLabel()));
allMedia.AddAll(allMediaData);
}
我正在尝试了解 ZKoss 的工作原理,特别是使用 MVVM 模式。
我在 JDK8 和 wildfly 10 上使用 ZK8.0.2.2 CE。
我有一个组合框和一个网格。我希望组合框 onSelect 事件触发网格更新。使用组合框中的所选项目作为参数更新网格。
问题是,应该由 onSelect 调用的 @Command 方法从未被调用,也从未触发更新。
还有一件事:如果我了解数据绑定的工作原理,那么 Combobox 上的 onSelect 参数甚至都不是必需的。 Grid 通过参数 model="@load(vm.allMedia)"
绑定到 ViewModel (allMedia) 中的 ListModel因此,如果 allMedia 发生变化,网格应该自动更新(类似于在具有绑定属性的 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 和数据库访问。)
我做错了吗?有更好的方法吗?
提前致谢。
@Command
在您的代码中有一个大写的 C 字母将其更改为 @command
并且它应该可以正常工作。
改成:
<combobox id="cmbType" width="150px" model="@load(vm.allType)"
selectedItem="@bind(vm.actualType)" onSelect="@command('updateTable')">
并且不要忘记在您的 updateTable 方法中添加 @NotifyChange("allMediaData")
@Command
@NotifyChange({"allMediaData","allMedia"})
public void updateTable() {
allMediaData.clear();
allMediaData.addAll(db.getMedia(actualType.getLabel()));
allMedia.AddAll(allMediaData);
}