afterCompose 从不在初始化时执行

afterCompose never executes on initialization

我有一个扩展 window 并实现 IdSpace、AfterCompose 的控制器。 但是 afterCompose 函数在控制器初始化时永远不会执行。无法弄清楚我错过了什么。我这部分的代码:

DataTemplateWindowController.java

public class DataTemplateWindowController extends Window implements IdSpace, AfterCompose {
   ...
   public DataTemplateWindowController() {
      Executions.createComponents("dataTemplate.zul", this, null);
      Selectors.wireComponents(this, this, false);
      Selectors.wireEventListeners(this, this);
   }

   @Override
   public void afterCompose() {
      Do something smart!!
   }
}

和初始化。 HomeWindowController.java

public class HomeWindowController extends SelectorComposer<Component> {
    ...

    @Wire
    Window homeWindow;

    DataTemplateWindowController fa2;

    public void setDataTemplate() {
        fa2 = new FA2WindowController();
        fa2.setParent(homeWindow);
    }
}

页面加载正常,但 afterCompose 函数从未执行。

我知道我可以避免实现 AfterCompose 然后 运行 初始化后的函数 fa2.afterCompose() 但我希望 AfterCompose 能够为我完成这项工作。

如您在 AfterCompose(org.zkoss.zk.ui.ext.AfterCompose)接口的 java文档中所见:

Implemented by a component if it wants to know when ZK loader created it. If this interface is implemented, {@link #afterCompose} is called, after ZK loader creates this component, all of its children, and assigns all properties defined in the ZUML page. It is so-called "compose".

因此方法 : "afterCompose" 永远不会被您自己的 java 代码(在您的示例中的方法 setDataTemplate() 中的代码)自动调用。仅当您在 ZUL 页面中使用您的组件时才会调用它。

而且在org.zkoss.zk.ui.ext.AfterCompose的Javadoc中也可以看到:

If it is created manually, it is caller's job to invoke {@link#afterCompose}.

如果你不需要在你的afterCompose过程中设置任何properties或者child,就不要使用这个接口,把你的代码放在constructor中,否则,你需要的时候需要手动调用它(通常在 SelectorComposer 的 doAfterCompose 中):

public class HomeWindowController extends SelectorComposer<Component> {
    ...

    @Wire
    Window homeWindow;

    DataTemplateWindowController fa2;

    @Override
    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp);
        setDataTemplate();
    }

    public void setDataTemplate() {
        fa2 = new FA2WindowController();
        fa2.setParent(homeWindow);
        fa2.afterCompose();
    }
}