根据复合组件中的动态列表渲染多个 <option> 元素
Render multiple <option> elements based on dynamic list in a composite component
我正在使用 JSF 2.2 和 Prime Faces 5.3。
我正在尝试创建具有动态选项的 html5 组件。
目标是创建类似于 f:selectItems 标签
的内容
目前我有以下用于数据列表标签的代码(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>
你能帮帮我吗?
谢谢!
您可以使用 <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>
注意 <cc:interface>
的 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;
}
}
现在您可以像 <f:selectItems>
一样使用它了。
<myTag:dataList id="test">
<myTag:options value="#{myBean.myCollection}" var="mySingleObj" itemValue="#{mySingleObj.value}" itemLabel="#{mySingleObj.label}" />
</myTag:dataList>
另请参阅:
- How iterate over List<T> and render each item in JSF Facelets
我正在使用 JSF 2.2 和 Prime Faces 5.3。
我正在尝试创建具有动态选项的 html5 组件。 目标是创建类似于 f:selectItems 标签
的内容目前我有以下用于数据列表标签的代码(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>
你能帮帮我吗? 谢谢!
您可以使用 <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>
注意 <cc:interface>
的 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;
}
}
现在您可以像 <f:selectItems>
一样使用它了。
<myTag:dataList id="test">
<myTag:options value="#{myBean.myCollection}" var="mySingleObj" itemValue="#{mySingleObj.value}" itemLabel="#{mySingleObj.label}" />
</myTag:dataList>
另请参阅:
- How iterate over List<T> and render each item in JSF Facelets