在自定义 ZK 组件中集成子组件的问题

问题描述 投票:0回答:1

我正在 ZK 中开发一个 ButtonGroup 自定义组件来容纳多个按钮链接,但我遇到了一个问题,即子组件未在宏组件内的预期容器内呈现。

    <button-group>
        <n:a href="forgot-password" class="text-xs text-blue-500 hover:underline">Forgot Password?</n:a>
        <n:a href="register" class="text-xs text-blue-500 hover:underline">Register</n:a>
    </button-group>

目标:我希望 标签在宏模板的特定分区 (childrenHost) 内呈现。

宏组件设置:

    <zk xmlns:n="not the link because no karma -_-">
        <div class="flex flex-row gap-1">
            <n:p>Hello</n:p>
            <n:div id="childrenHost" class="flex flex-row gap-1">
                <!-- Target for dynamic child append -->
            </n:div>
        </div>
    </zk>

Java 组件设置:

    package nl.example.org.webui.components;
    
    import org.zkoss.zk.ui.HtmlMacroComponent;
    import org.zkoss.zk.ui.Component;
    
    public class ButtonGroup extends HtmlMacroComponent {
        public ButtonGroup() {
            setMacroURI("/components/form/buttonGroup.zul");
            compose();
        }
    
        @Override
        public void afterCompose() {
            super.afterCompose();
            // Attempts to append children to 'childrenHost'
        }
    }

尽管尝试了各种方法,例如在 afterCompose 中以编程方式操作组件层次结构,但子级仍然在指定的childrenHost div 之外呈现。

是否有人遇到过类似的挑战,或者是否有人对如何确保子组件正确集成到宏组件的指定部分有见解?任何帮助或建议将不胜感激!

zk zkoss
1个回答
0
投票

此结构的主要问题是,如果没有已创建为该组件的子组件的现有组件,HtmlMacroComponent 只会实例化提供给它的模板 URI 的内容。

注意:默认情况下,宏组件充当标签

此外,您不应该在构造函数期间调用 compose。当组件已经在 UI 中时,应在组合阶段调用 Compose。

结果是您有以下任一工作流程:

  • 如果您直接将组件作为子组件从外部页面传递给 MacroComponent,这些子组件会阻止从模板 URI 创建组件

  • 如果不从外部页面传递组件,您可以从模板URI创建组件

因此,由于您的目标是将内容插入到宏内容内的主机中,因此您不应该直接从外部页面传递子级,而应将其作为模板传递。然后,您在宏组件的 compose 方法中构建该模板。

只需连接您的主机组件即可将其用作构建组件的目标。 通过这种方式,您可以控制何时以及何时创建子组件并将其添加到实际组件结构中。

见下图:

外页:

<div>
    <mymacro>
        <template name="macroContent">
            <n:div class="foo">
                <label value="bar"/>
            </n:div>
        </template>
    </mymacro>
</div>

宏组件模板中:

<span sclass="mymacro">
    <textbox value="myMacroContent1"/>
    <div id="mymacrohost" sclass="mymacrohost"></div>
    <textbox value="myMacroContent2"/>
</span>

宏组件类中

@Wire("#mymacrohost")
Div mymacrohost;

@Override
protected void compose() {
    super.compose();
    Template macroContent = Templates.lookup(this, "macroContent");
    macroContent.create(mymacrohost, null, null, null); //composer and resolve null, but can pass if needed.
}
© www.soinside.com 2019 - 2024. All rights reserved.