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);
}