基于复合组件

时间:2016-05-14 17:39:14

标签: jsf options composite-component html-datalist

我在Prime Faces 5.3中使用JSF 2.2。

我尝试使用动态选项创建html5组件。 目标是创建类似于f:selectItems标签

的东西

目前我已经为datalist标签提供了以下代码(datalist.xhtml文件)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns:cc="http://xmlns.jcp.org/jsf/composite">

<cc:interface></cc:interface>

<cc:implementation>
    <datalist id="#{cc.attrs.id}">
        <cc:insertChildren/>
    </datalist>
</cc:implementation>

</html>

以及单个选项(option.xhtml文件)的以下内容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns:cc="http://xmlns.jcp.org/jsf/composite">

<cc:interface>
    <cc:attribute name="value" type="java.lang.String" default=""/>
    <cc:attribute name="label" type="java.lang.String" default=""/>
</cc:interface>

<cc:implementation>
    <option value="#{cc.attrs.value}" label="#{cc.attrs.label}"/>
</cc:implementation>

</html>

通过这种方法,我可以创建类似这样的东西

<myTag:dataList id="test">
    <myTag:option value="1" label="label1"/>
    <myTag:option value="2" label="label2"/>
    <myTag:option value="3" label="label3"/>
</myTag:dataList>

但是我需要一些允许我拥有动态选项列表的东西。我希望写下面的代码(或类似的)

<myTag:dataList id="test">
    <myTag:options value="#{myBean.myCollection}" var="mySingleObj" itemValue="mySingleObj.value" itemLabel="mySingleObj.label"/>
</myTag:dataList>
你能帮帮我吗? 谢谢!

1 个答案:

答案 0 :(得分:3)

您可以使用<ui:repeat>迭代集合,这是一个基本示例。

<ui:repeat value="#{bean.options}" var="option">
    <option value="#{option.value}">#{option.label}</option>
</ui:repeat>

仅在复合中声明其var变得棘手,因为var属性中不允许使用值表达式。所以你不能做var="#{cc.attrs.var}"之类的事情。为此,您需要创建一个支持组件,将<ui:repeat>绑定到它,并在postAddToView事件期间手动评估var属性并在组件上设置它。

<cc:interface componentType="optionsComposite">
    <cc:attribute name="value" />
    <cc:attribute name="var" />
    <cc:attribute name="itemValue" />
    <cc:attribute name="itemLabel" />
</cc:interface>
<cc:implementation>
    <f:event type="postAddToView" listener="#{cc.init}" />

    <ui:repeat binding="#{cc.repeat}" value="#{cc.attrs.value}">
        <option value="#{cc.attrs.itemValue}">#{cc.attrs.itemLabel}</option>
    </ui:repeat>
</cc:implementation>

请注意componentType的{​​{1}}属性。它必须引用<cc:interface>值。

@FacesComponent

现在您可以像@FacesComponent("optionsComposite") public class OptionsComposite extends UINamingContainer { private UIComponent repeat; public void init() { repeat.getAttributes().put("var", getAttributes().get("var")); } public UIComponent getRepeat() { return repeat; } public void setRepeat(UIComponent repeat) { this.repeat = repeat; } } 一样使用它。

<f:selectItems>

另见: