ZK 如何以只读模式创建容器( Window Div 布局)?

ZK How to create container in readonly mode ( Window Div Layout)?

我正在开发 ZK 应用程序,其中包含的角色很少。 对于 "Guest" 角色,我必须将所有组件设置为只读模式。 那么如何在 ZK 应用程序中以只读模式创建容器(Window Div 布局)?​​

容器不是设置 enabled/disabled 属性 的正确位置。它是一个包含各种其他组件的 "passive" 元素。

要enable/disable输入,您必须直接在textboxcombobox、...等输入组件上设置属性。他们通常有一个 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 排除了按钮,这样您仍然可以按下按钮)