我问了this问题,虽然答案直接满足了我的需求,但我仍然觉得这个特定问题需要更简单的解决方案。
我希望有一个复合组件接受一个项目列表(商定的项目类型,以便成员可以在复合组件中自由使用)
CC(复合组件)显示项目列表,允许添加和减少项目。
我想以最简单有效的方式做到这一点。
为了说明问题,举个例子:
定义应该相当简单(当然,除非:-)):
<special:dynamicFieldList value="#{bean.fieldList} />
Field
对象的最抽象形式是:
public class Field{
String uuid;
String value;
}
我猜就是这样。 你会如何以简单的方式实现这一点?
谢谢!
答案 0 :(得分:24)
我在具有支持<h:dataTable>
的复合组件中使用UIComponent
,您可以通过componentType
的{{1}}属性进行绑定。在支持<composite:interface>
中,您可以维护UIComponent
并定义操作。
DataModel
dynamicFieldList.xhtml
(如果需要,<ui:composition
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
>
<cc:interface componentType="dynamicFieldList">
<cc:attribute name="value" type="java.util.List" required="true" />
</cc:interface>
<cc:implementation>
<h:dataTable id="table" binding="#{cc.table}" value="#{cc.attrs.value}" var="field">
<h:column><h:outputLabel value="#{field.label}" /></h:column>
<h:column><h:inputText value="#{field.value}" /></h:column>
<h:column><h:commandButton value="remove" action="#{cc.remove}" /></h:column>
</h:dataTable>
<h:commandButton value="add" action="#{cc.add}" />
</cc:implementation>
</ui:composition>
可以是您的复合字段组件)
<h:inputText>
com.example.DynamicFieldList
按如下方式使用:
@FacesComponent(value="dynamicFieldList") // To be specified in componentType attribute.
@SuppressWarnings({"rawtypes", "unchecked"}) // We don't care about the actual model item type anyway.
public class DynamicFieldList extends UINamingContainer {
private UIData table;
public void add() {
((List) getAttributes().get("value")).add(new Field("somelabel"));
}
public void remove() {
((List) getAttributes().get("value")).remove(table.getRowData());
}
public UIData getTable() {
return table;
}
public void setTable(UIData table) {
this.table = table;
}
}
只有这个
<h:form>
<my:dynamicFieldList value="#{bean.fields}" />
</h:form>
和
@ManagedBean
@ViewScoped
public class Bean implements Serializable {
private List<Field> fields;
public Bean() {
fields = new ArrayList<>();
}
public List<Field> getFields() {
return fields;
}
}