在h:panelGrid中使用多个子组件的自定义Facelets标签

3
我已经编写了一个扩展UIComponentBase的自定义标签。
encodeBegin方法中,它会添加多个子组件(UIComponent)。
为了布局目的,我想将这些子组件嵌套在一个h:panelGrid中,但是标签会妨碍这里的操作。 ExampleTag.java
private ExampleTag extends UIComponentBase {

    public void encodeBegin(FacesContext context) throws IOException {
        getChildren().add(new HtmlLabel());
        getChildren().add(new HtmlOutputText();
    }
}

ExampleOutput.xhtml

<html>
    <h:panelGrid columns="2">
       <foo:exampleTag />
       <foo:exampleTag />
    </h:panelGrid>
</html>

生成的输出将在同一个单元格中具有HtmlLabelHtmlOutput组件,但我希望它们在一行中,即两个单元格

@user745359:欢迎来到StackOverflow!我建议您更改您的用户名和(可选)头像。祝好! - Alba Mendez
1个回答

3
  1. h:panelGrid仅控制其自身的子元素的布局(而不是其子元素的子元素)
  2. 每个<foo:exampleTag />创建一个组合控件(带有其自己的子元素)

如果您想向h:panelGrid添加多个控件,请使用其他模板机制。

例如,这个h:panelGrid使用了一个ui:include

    <h:panelGrid columns="2">
      <ui:include src="gridme.xhtml">
        <ui:param name="foo" value="Hello,"/>
        <ui:param name="bar" value="World!"/>
      </ui:include>
      <ui:include src="gridme.xhtml">
        <ui:param name="foo" value="Hello,"/>
        <ui:param name="bar" value="Nurse!"/>
      </ui:include>
    </h:panelGrid>

包含的组合文件:

<!-- gridme.xhtml -->
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html">
  <h:outputText value="#{foo}" />
  <h:outputText value="#{bar}" />
</ui:composition>

视图输出的子集:
<table>
<tbody>
<tr>
<td>Hello,</td>
<td>World!</td>
</tr>
<tr>
<td>Hello,</td>
<td>Nurse!</td>
</tr>
</tbody>
</table>

请注意上述实现方式 - 由于没有复合控件和因此没有NamespaceContainer来确保子项命名空间唯一,因此您不能在gridme.xhtml中显式设置任何ID。
组件不是标记。
public void encodeBegin(FacesContext context) throws IOException {
  getChildren().add(new HtmlLabel());
  getChildren().add(new HtmlOutputText();
}

这种构建组合控件的方式不可取。如果你这样做,每次组件被呈现时都会添加新的控件。你也不应该在构造函数中这样做;那样会导致问题。没有好的方法在控件内部添加子控件;它应该由视图外部完成(请参见上文)或者标签来完成。


非常感谢,这是一个基本的设计错误。我通过检查childCount()来“修复”在渲染阶段添加组件的问题,但这也不是一个好主意! - wintersolutions

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接