如何使用JSF 2.0复合组件实现动态列表?

16

我在这里提出了一个问题,虽然回答直接满足了我的需求,但是我仍然觉得针对这个特定问题应该有更简单的解决方案。

我想要一个复合组件,它可以接受一个项目列表(同意项目类型,因此成员可以在复合组件内自由使用)

该CC(复合组件)显示项目列表并允许添加和删除项目。

我希望以最简单和高效的方式实现这一点。

为了说明问题,举个例子:

enter image description here

定义应该相当简单(除非当然不是 :-)):

<special:dynamicFieldList value="#{bean.fieldList} />

一个Field对象最抽象的形式是:

public class Field{
 String uuid;
 String value;
}

我猜就是这样了。你如何以简单的方式实现它?

谢谢!

1个回答

25
我会在组合组件中使用<h:dataTable>,并使用<composite:interface>componentType属性绑定支持的UIComponent。然后,在支持的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


(注:本文为IT技术相关内容)
@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;
    }

}

并且

public class Field implements Serializable {

    private String label;
    private String value;

    public Field() {
        //
    }

    public Field(String label) {
        this.label = label;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

@BalusC 谢谢。但是我该如何将它封装到组合组件中?我需要将“remove”和“add”方法作为属性传递吗?我想那应该是可以接受的。 - Ben
1
我更新了答案。关键是使用“后备UIComponent”,在其中定义操作。 - BalusC
3
好的! :) 我在想复合组件中嵌入表单的形式。它现在很方便,但也意味着这个特定的组件不能在另一个表单中使用。 - Arjan Tijms
2
@Arjan:把表单放在外面确实更有意义。我会编辑这个例子。 - BalusC
这个解决方案对于JSF 2.2仍然有效吗?因为在我的情况下,添加/删除按钮无法正常工作。谢谢! - AndrewG10i

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