【问题标题】:Render multiple <option> elements based on dynamic list in a composite component基于复合组件中的动态列表渲染多个 <option> 元素
【发布时间】:2016-05-14 17:39:14
【问题描述】:

我正在使用 JSF 2.2 和 Prime Faces 5.3。

我正在尝试创建一个带有动态选项的 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>

你能帮帮我吗? 谢谢!

【问题讨论】:

  • 为什么不使用简单的 h:selectOneMenu 之类的?您可以在 cc 中使用 ui:repeat 来迭代您的选项。或者你可以复制butterfaces.org/butterfaces-showcase/treebox.jsf的一些代码,自己构建一个java组件。
  • 因为,通过 datalist,您可以使用来自 html 5 的自动完成功能
  • 所以我更喜欢使用 ButterFaces 或者只是复制代码。 TreeBox 以简单的方式支持列表、树和自动完成。

标签: jsf options composite-component html-datalist


【解决方案1】:

您可以使用&lt;ui:repeat&gt; 来遍历集合,这是一个基本示例。

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

仅在复合中声明其var 会变得很棘手,因为在var 属性中不允许使用值表达式。所以你不能做像var="#{cc.attrs.var}" 这样的事情。为此,您需要创建一个支持组件,将&lt;ui:repeat&gt; 绑定到它,并在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>

注意&lt;cc:interface&gt;componentType 属性。它必须引用 @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;
    }

}

现在你可以像&lt;f:selectItems&gt;一样使用它了。

<myTag:dataList id="test">
    <myTag:options value="#{myBean.myCollection}" var="mySingleObj" itemValue="#{mySingleObj.value}" itemLabel="#{mySingleObj.label}" />
</myTag:dataList>

另见:

【讨论】:

  • 你好 BalusC。像往常一样,你的答案就像一个魅力。只是一个快速的问题。我正在使用 netbeans 作为 IDE。为什么告诉我“ui:repeat”标签中缺少“var”?它链接了旧的 JSF 版本?
猜你喜欢
  • 2020-06-10
  • 1970-01-01
  • 2020-10-28
  • 2018-12-21
  • 2017-02-03
  • 1970-01-01
  • 1970-01-01
  • 2019-11-26
  • 2017-11-06
相关资源
最近更新 更多