ZK,自定义组件。一个值的不同功能(加载和保存)
ZK, custom component. Different function (load and save) for one value
ZK 框架。我有自定义组件 v_dualListbox.zul:
<hlayout hflex="1">
<listbox id="candidateLb" hflex="1" vflex="true" multiple="true" rows="8">
<template name="model">
<listitem>
<listcell label="${each.description}"/>
</listitem>
</template>
</listbox>
<vbox spacing="10px" width="24px">
<image style="cursor:pointer" id="chooseAllBtn" src="/img/001_25.png"/>
<image style="cursor:pointer" id="chooseBtn" src="/img/001_25.png"/>
<image style="cursor:pointer" id="removeBtn" src="/img/001_27.png"/>
<image style="cursor:pointer" id="removeAllBtn" src="/img/001_27.png"/>
</vbox>
<listbox id="chosenLb" hflex="1" vflex="true" multiple="true" rows="8">
<template name="model">
<listitem>
<listcell label="${each.description}"/>
</listitem>
</template>
</listbox> </hlayout>
我在 zul 页面上使用它:
<?component name="dual-listbox" extends="div" class="ru.it_constanta.pguAdmin.components.DualListbox"?>
<dual-listbox id="scopeDualLBox" chosenDataList="@bind(vm.orgScopeList)" model="@bind(vm.scopeList)"/>
DualListbox.java:
package ru.it_constanta.pguAdmin.components;
import ...
public class DualListbox<T> extends HtmlMacroComponent implements IdSpace {
private static final long serialVersionUID = 5183321186606483396L;
@Wire
private Listbox candidateLb;
@Wire
private Listbox chosenLb;
private ListModelList<T> candidateModel = new ListModelList<>();
private ListModelList<T> chosenDataModel = new ListModelList<>();
private boolean isLoad = false;
public DualListbox() {
Executions.createComponents("v_dualListbox.zul", this, null);
Selectors.wireComponents(this, this, false);
Selectors.wireEventListeners(this, this);
chosenLb.setModel(chosenDataModel = new ListModelList<T>());
chosenDataModel.setMultiple(true);
}
@Listen("onClick = #chooseBtn")
public void chooseItem() {
Events.postEvent(new ChooseEvent(this, chooseOne()));
}
@Listen("onClick = #removeBtn")
public void unchooseItem() {
Events.postEvent(new ChooseEvent(this, unchooseOne()));
}
@Listen("onClick = #chooseAllBtn")
public void chooseAllItem() {
Events.postEvent(new ChooseEvent(this, chooseAll()));
}
@Listen("onClick = #removeAllBtn")
public void unchooseAllItem() {
Events.postEvent(new ChooseEvent(this, unchooseAll()));
}
/**
* Set new candidate ListModelList.
*
* @param candidate is the data of candidate list model
*/
public void setModel(List<T> candidate) {
candidateLb.setModel(this.candidateModel = new ListModelList<>(candidate));
this.candidateModel.setMultiple(true);
chosenDataModel.clear();
}
@ComponentAnnotation(
"@ZKBIND(ACCESS=load, LOAD_EVENT=onLoad)")
public void setChosenDataList(List<T> chosen) {
chosenDataModel.addAll(chosen);
candidateModel.removeAll(chosen);
}
/**
* @return current chosen data list
*/
@ComponentAnnotation(
"@ZKBIND(ACCESS=save, SAVE_EVENT=onChoose)")
public List<T> getChosenDataList() {
return new ArrayList<>(chosenDataModel);
}
private Set<T> chooseOne() {
Set<T> set = candidateModel.getSelection();
chosenDataModel.addAll(set);
candidateModel.removeAll(set);
return set;
}
private Set<T> unchooseOne() {
Set<T> set = chosenDataModel.getSelection();
candidateModel.addAll(set);
chosenDataModel.removeAll(set);
return set;
}
private Set<T> chooseAll() {
chosenDataModel.addAll(candidateModel);
candidateModel.clear();
return chosenDataModel.getSelection();
}
private Set<T> unchooseAll() {
candidateModel.addAll(chosenDataModel);
chosenDataModel.clear();
return candidateModel.getSelection();
}
// Customized Event
public class ChooseEvent extends Event {
private static final long serialVersionUID = -7334906383953342976L;
public ChooseEvent(Component target, Set<T> data) {
super("onChoose", target, data);
}
}
}
来自数据库的数据。在加载页面上,我想放置已有对象的实体列表 (orgScopeList),我想在 chosenLb 列表框中看到它们。我为此使用 chosenDataList 属性。我还想将所选对象保存在同一个列表(orgScopeList)中,i。 e 当客户端选择或取消选择更多实体时,我想将其保存在 orgScopeList 中,这就是我使用 @bind 注释(用于加载和保存)的原因。所以我需要为两个命令(加载和保存)监听两个事件 onLoad 和我的 onChoose。我用 @ComponentAnnotation 写了两个方法,但是 setChosenDataList 不起作用,加载页面上没有任何反应,我不知道为什么。
我希望有人理解我:) 请帮忙!
感谢 Malte Hartwig 的回答,他的两个建议都有效(仅在 getter 上使用 @ComponentAnnotations
并将 onCreate
事件用作 LOAD_EVENT), 这就是我 DualListbox.java:
中现在的内容
public void setChosenDataList(List<T> chosen) {
chosenDataModel.clear();
chosenDataModel.addAll(chosen);
candidateModel.removeAll(chosen);
}
@ComponentAnnotation(
"@ZKBIND(ACCESS=both, SAVE_EVENT=onChoose, LOAD_EVENT=onCreate)")
public List<T> getChosenDataList() {
return new ArrayList<>(chosenDataModel);
}
但重要的是要记住 LOAD_EVENT 也在 SAVE_EVENT 之后起作用,所以这就是写 chosenDataModel.clear();
的原因。
ZK 框架。我有自定义组件 v_dualListbox.zul:
<hlayout hflex="1">
<listbox id="candidateLb" hflex="1" vflex="true" multiple="true" rows="8">
<template name="model">
<listitem>
<listcell label="${each.description}"/>
</listitem>
</template>
</listbox>
<vbox spacing="10px" width="24px">
<image style="cursor:pointer" id="chooseAllBtn" src="/img/001_25.png"/>
<image style="cursor:pointer" id="chooseBtn" src="/img/001_25.png"/>
<image style="cursor:pointer" id="removeBtn" src="/img/001_27.png"/>
<image style="cursor:pointer" id="removeAllBtn" src="/img/001_27.png"/>
</vbox>
<listbox id="chosenLb" hflex="1" vflex="true" multiple="true" rows="8">
<template name="model">
<listitem>
<listcell label="${each.description}"/>
</listitem>
</template>
</listbox> </hlayout>
我在 zul 页面上使用它:
<?component name="dual-listbox" extends="div" class="ru.it_constanta.pguAdmin.components.DualListbox"?>
<dual-listbox id="scopeDualLBox" chosenDataList="@bind(vm.orgScopeList)" model="@bind(vm.scopeList)"/>
DualListbox.java:
package ru.it_constanta.pguAdmin.components;
import ...
public class DualListbox<T> extends HtmlMacroComponent implements IdSpace {
private static final long serialVersionUID = 5183321186606483396L;
@Wire
private Listbox candidateLb;
@Wire
private Listbox chosenLb;
private ListModelList<T> candidateModel = new ListModelList<>();
private ListModelList<T> chosenDataModel = new ListModelList<>();
private boolean isLoad = false;
public DualListbox() {
Executions.createComponents("v_dualListbox.zul", this, null);
Selectors.wireComponents(this, this, false);
Selectors.wireEventListeners(this, this);
chosenLb.setModel(chosenDataModel = new ListModelList<T>());
chosenDataModel.setMultiple(true);
}
@Listen("onClick = #chooseBtn")
public void chooseItem() {
Events.postEvent(new ChooseEvent(this, chooseOne()));
}
@Listen("onClick = #removeBtn")
public void unchooseItem() {
Events.postEvent(new ChooseEvent(this, unchooseOne()));
}
@Listen("onClick = #chooseAllBtn")
public void chooseAllItem() {
Events.postEvent(new ChooseEvent(this, chooseAll()));
}
@Listen("onClick = #removeAllBtn")
public void unchooseAllItem() {
Events.postEvent(new ChooseEvent(this, unchooseAll()));
}
/**
* Set new candidate ListModelList.
*
* @param candidate is the data of candidate list model
*/
public void setModel(List<T> candidate) {
candidateLb.setModel(this.candidateModel = new ListModelList<>(candidate));
this.candidateModel.setMultiple(true);
chosenDataModel.clear();
}
@ComponentAnnotation(
"@ZKBIND(ACCESS=load, LOAD_EVENT=onLoad)")
public void setChosenDataList(List<T> chosen) {
chosenDataModel.addAll(chosen);
candidateModel.removeAll(chosen);
}
/**
* @return current chosen data list
*/
@ComponentAnnotation(
"@ZKBIND(ACCESS=save, SAVE_EVENT=onChoose)")
public List<T> getChosenDataList() {
return new ArrayList<>(chosenDataModel);
}
private Set<T> chooseOne() {
Set<T> set = candidateModel.getSelection();
chosenDataModel.addAll(set);
candidateModel.removeAll(set);
return set;
}
private Set<T> unchooseOne() {
Set<T> set = chosenDataModel.getSelection();
candidateModel.addAll(set);
chosenDataModel.removeAll(set);
return set;
}
private Set<T> chooseAll() {
chosenDataModel.addAll(candidateModel);
candidateModel.clear();
return chosenDataModel.getSelection();
}
private Set<T> unchooseAll() {
candidateModel.addAll(chosenDataModel);
chosenDataModel.clear();
return candidateModel.getSelection();
}
// Customized Event
public class ChooseEvent extends Event {
private static final long serialVersionUID = -7334906383953342976L;
public ChooseEvent(Component target, Set<T> data) {
super("onChoose", target, data);
}
}
}
来自数据库的数据。在加载页面上,我想放置已有对象的实体列表 (orgScopeList),我想在 chosenLb 列表框中看到它们。我为此使用 chosenDataList 属性。我还想将所选对象保存在同一个列表(orgScopeList)中,i。 e 当客户端选择或取消选择更多实体时,我想将其保存在 orgScopeList 中,这就是我使用 @bind 注释(用于加载和保存)的原因。所以我需要为两个命令(加载和保存)监听两个事件 onLoad 和我的 onChoose。我用 @ComponentAnnotation 写了两个方法,但是 setChosenDataList 不起作用,加载页面上没有任何反应,我不知道为什么。 我希望有人理解我:) 请帮忙!
感谢 Malte Hartwig 的回答,他的两个建议都有效(仅在 getter 上使用 @ComponentAnnotations
并将 onCreate
事件用作 LOAD_EVENT), 这就是我 DualListbox.java:
public void setChosenDataList(List<T> chosen) {
chosenDataModel.clear();
chosenDataModel.addAll(chosen);
candidateModel.removeAll(chosen);
}
@ComponentAnnotation(
"@ZKBIND(ACCESS=both, SAVE_EVENT=onChoose, LOAD_EVENT=onCreate)")
public List<T> getChosenDataList() {
return new ArrayList<>(chosenDataModel);
}
但重要的是要记住 LOAD_EVENT 也在 SAVE_EVENT 之后起作用,所以这就是写 chosenDataModel.clear();
的原因。