ZK 如何以只读模式创建容器( Window Div 布局)?
ZK How to create container in readonly mode ( Window Div Layout)?
我正在开发 ZK 应用程序,其中包含的角色很少。
对于 "Guest" 角色,我必须将所有组件设置为只读模式。
那么如何在 ZK 应用程序中以只读模式创建容器(Window Div 布局)?
容器不是设置 enabled/disabled 属性 的正确位置。它是一个包含各种其他组件的 "passive" 元素。
要enable/disable输入,您必须直接在textbox
、combobox
、...等输入组件上设置属性。他们通常有一个 disabled
属性 如果客户端处于只读模式,则必须将其设置为 true
。
使用 MVVM 时,您可以通过将所有组件的禁用 属性 绑定到同一视图模型来简化此操作 属性:
<zk>
<window title="Enable/Disable" border="normal" width="600px"
apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('pkg$.TestVM')" >
<hbox>
<vbox>
<checkbox label='readonly' checked='@bind(vm.readonly)' />
</vbox>
<div>
<textbox value='test' disabled='@bind(vm.readonly)' />
<checkbox label='test' disabled='@bind(vm.readonly)' />
</div>
</hbox>
</window>
</zk>
Here 你可以找到一个工作示例 fiddle.
是的,您也可以在 MVVM 中执行此操作。
所以让我们从头开始。
您需要像 the answer you reffering 中那样连接一些组件:
@Wire("disable")
private List<Disable> allToDisable;
private boolean disable;
第二件事是,实现用于禁用的 AfterCompose 和用于检查状态的 Init。
在普通的 MVVM 中,你几乎不需要使用 @AfterCompose
,但是当你需要连接这样的解决方案时,你将需要它。
@Init
public void init() {
disable = checkForGuest();
}
/**
* This method will launch when all components are created.
* @param view to wire the components
*/
@AfterCompose
public void afterCompose(@ContextParam(ContextType.VIEW) Component view) {
Selectors.wireComponents(view, this, false); // after this your private fields are wired.
disableAll(disable);
}
private void disableAll(boolean disableStatus){
for(Disable d : allToDisable) {
d.setDisabled(disableStatus);
}
}
你要知道的是@Init先触发,AfterCompose后触发
编辑:
那是因为数据绑定发生在 @AfterCompose
之后。
您可以为 disable
和 zul 添加一个 getter :
<checkbox disabled="@load(yourValue or vm.disabled)"/>
有了这个,如果 2 个中的 1 个为真,则复选框始终处于禁用状态。
最后编辑:
在下班回家的路上,没有下降的解决方案,我不能这样下去。
经过一夜安眠,我已经为您找到了解决方案。
@AfterCompose
public void afterCompose(@SelectorParam("*") Collection<Component> allToDisable, @ContextParam(ContextType.BINDER)Binder binder) {
for(Component comp : allToDisable) {
if (comp instanceof Disable) {
((Disable)comp).setDisabled(disable);
binder.removeBindings(comp, "disabled");
}
}
}
**解释:**
虽然昨天我没有测试 @Wire("disable")
是否有效,但我没有在 ZK Fiddle.
中使用它
所以首先,我想摆脱 @Wire
所以我们使用 @SelectorParam
来做同样的事情,这样我们不需要调用 Selectors
.
我在使用 @Wire
或 @SelectorParam
时遇到了同样的问题,我在列表中从来没有任何组件。
所以现在,我们只是获取视图中的每个组件并检查它是否是 Disable
接口的实例, 实际上是相同的,这样你甚至可以说不是按钮。
然后第二件事就是删除该组件的属性 disabled
的绑定。
您可以通过使用 @ContextParam
注释从上下文中询问 Binder
来做到这一点。
最后,我们通过 binder.removeBindings(Component, String);
.
移除绑定
注意,不要删除与 binder.removeBindings(Component);
的完整绑定,因为那时您对值的绑定也消失了。
You can check it out in this fiddle(我通过检查 Textbox
排除了按钮,这样您仍然可以按下按钮)
我正在开发 ZK 应用程序,其中包含的角色很少。 对于 "Guest" 角色,我必须将所有组件设置为只读模式。 那么如何在 ZK 应用程序中以只读模式创建容器(Window Div 布局)?
容器不是设置 enabled/disabled 属性 的正确位置。它是一个包含各种其他组件的 "passive" 元素。
要enable/disable输入,您必须直接在textbox
、combobox
、...等输入组件上设置属性。他们通常有一个 disabled
属性 如果客户端处于只读模式,则必须将其设置为 true
。
使用 MVVM 时,您可以通过将所有组件的禁用 属性 绑定到同一视图模型来简化此操作 属性:
<zk>
<window title="Enable/Disable" border="normal" width="600px"
apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('pkg$.TestVM')" >
<hbox>
<vbox>
<checkbox label='readonly' checked='@bind(vm.readonly)' />
</vbox>
<div>
<textbox value='test' disabled='@bind(vm.readonly)' />
<checkbox label='test' disabled='@bind(vm.readonly)' />
</div>
</hbox>
</window>
</zk>
Here 你可以找到一个工作示例 fiddle.
是的,您也可以在 MVVM 中执行此操作。
所以让我们从头开始。
您需要像 the answer you reffering 中那样连接一些组件:
@Wire("disable")
private List<Disable> allToDisable;
private boolean disable;
第二件事是,实现用于禁用的 AfterCompose 和用于检查状态的 Init。
在普通的 MVVM 中,你几乎不需要使用 @AfterCompose
,但是当你需要连接这样的解决方案时,你将需要它。
@Init
public void init() {
disable = checkForGuest();
}
/**
* This method will launch when all components are created.
* @param view to wire the components
*/
@AfterCompose
public void afterCompose(@ContextParam(ContextType.VIEW) Component view) {
Selectors.wireComponents(view, this, false); // after this your private fields are wired.
disableAll(disable);
}
private void disableAll(boolean disableStatus){
for(Disable d : allToDisable) {
d.setDisabled(disableStatus);
}
}
你要知道的是@Init先触发,AfterCompose后触发
编辑:
那是因为数据绑定发生在 @AfterCompose
之后。
您可以为 disable
和 zul 添加一个 getter :
<checkbox disabled="@load(yourValue or vm.disabled)"/>
有了这个,如果 2 个中的 1 个为真,则复选框始终处于禁用状态。
最后编辑:
在下班回家的路上,没有下降的解决方案,我不能这样下去。
经过一夜安眠,我已经为您找到了解决方案。
@AfterCompose
public void afterCompose(@SelectorParam("*") Collection<Component> allToDisable, @ContextParam(ContextType.BINDER)Binder binder) {
for(Component comp : allToDisable) {
if (comp instanceof Disable) {
((Disable)comp).setDisabled(disable);
binder.removeBindings(comp, "disabled");
}
}
}
**解释:**
虽然昨天我没有测试 @Wire("disable")
是否有效,但我没有在 ZK Fiddle.
中使用它
所以首先,我想摆脱 @Wire
所以我们使用 @SelectorParam
来做同样的事情,这样我们不需要调用 Selectors
.
我在使用 @Wire
或 @SelectorParam
时遇到了同样的问题,我在列表中从来没有任何组件。
所以现在,我们只是获取视图中的每个组件并检查它是否是 Disable
接口的实例, 实际上是相同的,这样你甚至可以说不是按钮。
然后第二件事就是删除该组件的属性 disabled
的绑定。
您可以通过使用 @ContextParam
注释从上下文中询问 Binder
来做到这一点。
最后,我们通过 binder.removeBindings(Component, String);
.
移除绑定
注意,不要删除与 binder.removeBindings(Component);
的完整绑定,因为那时您对值的绑定也消失了。
You can check it out in this fiddle(我通过检查 Textbox
排除了按钮,这样您仍然可以按下按钮)