Jsf 2 PrimeFaces datatable,具有使用较新Mojarra 2.1版本的任何列内容的动态列

Jsf 2 PrimeFaces datatable,具有使用较新Mojarra 2.1版本的任何列内容的动态列,jsf-2,primefaces,datatable,mojarra,view-scope,Jsf 2,Primefaces,Datatable,Mojarra,View Scope,我们正在GlassFish 3.1.2.2上运行JavaEE6+PrimeFaces3.5.28+JSF2.1.6(目前) 我们对数据表的要求是具有动态列,基本上可以是任何内容,即简单输出文本、复杂输出文本、格式化日期、格式化数字、布尔值显示是/否(取决于语言)、枚举值显示其值标签(取决于语言)、按钮、链接(见我的第一条评论)-你明白了 我们通过使用+构造解决了我们的需求: 下面是超级类“BaseColumnHandler的相关部分: public abstract class BaseColu

我们正在GlassFish 3.1.2.2上运行JavaEE6+PrimeFaces3.5.28+JSF2.1.6(目前)

我们对数据表的要求是具有动态列,基本上可以是任何内容,即简单输出文本、复杂输出文本、格式化日期、格式化数字、布尔值显示是/否(取决于语言)、枚举值显示其值标签(取决于语言)、按钮、链接(见我的第一条评论)-你明白了

我们通过使用
+
构造
解决了我们的需求:

下面是超级类“
BaseColumnHandler
的相关部分:

public abstract class BaseColumnHandler implements ColumnHandler, Serializable
{
    // recent order of columns as string, e.g. "active nbr code bank-code ..."
    private String       recentOrder;

    private List<Column> boundColumns;

    /**
     * The getter for the Facelet c:forEach. (Will reload and parse the recent order on any request from the UI.)
     */
    public List<Column> getBoundColumns()
    {
        if ( this.boundColumns == null )
        {
            List<Column> shownColumns = new ArrayList<Column>();

            // parse the string of visible columns as getRecentOrder() loaded it from the DB
            String order = this.getRecentOrder().trim();
            String[] columnIds = StringUtils.split( order, ' ' );

            // sub classes must implement newConfigurableColumns()
            List<Column> shownColumns = this.newConfigurableColumns();

            for ( String columnId : columnIds )
            {
                // some filtering going on to filter hidden columns (assume this does what it should)
                ...
            }

            // assign visible columns only
            this.boundColumns = shownColumns;
        }

        return this.boundColumns;
    }

    /**
     * Creates a new list of all generally configurable columns.
     * 
     * @return
     */
    protected abstract List<Column> newConfigurableColumns();

    ...
}
  • 使用
  • 如果查看
    DepotManagerColumnHandler
    中更复杂的JSF表达式,如
    “#{notempty dep.employee?dep.employee.nbr:”“}”
    ,结果如下 如果不存在
    employee
    关系,则在列中显示空字符串(该员工是可选的)。使用
    p:columns
    如showcase中所示,无法正常工作(只有标题文本显示正确):

    代码:

    此尝试与1非常相似,但会导致异常:

    Caused by: java.lang.IllegalArgumentException: Empty id attribute is not allowed
        at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:566)
        at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:370)
        at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.assignUniqueId(ComponentTagHandlerDelegateImpl.java:369)
        at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:172)
        at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
        at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
        at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:187)
    
    问题

    如何在Mojarra 2.1.22+环境中解决PrimeFaces数据表中的动态列,该环境要求完全自定义列内容(最好使用视图范围的bean)


    顺便说一句,我们也在使用Seam 3通过CDI获取查看范围…
    @Named
    +
    @ViewScoped

    好吧,你说你使用带有按钮、链接等的列,但是在
    createColumnWithCss
    方法中,你只创建输出文本列,对吗?我缺少什么?我从未见过这种灵活性要求在组件中,好奇。我相信还有第三个选项可以为您提供更大的灵活性,使用和编写您自己的编码器。通过这种方式,您可以用java定义组件的呈现行为,而不是xhtml,因为xhtml有更多的限制。好吧,我发布的示例来自一个更简单的应用程序,因此实际上是链接,但是吨列没有显示。正如我所想的,我们可能不需要按钮和链接列,因为它们通常位于可配置列的最左侧或右侧。因此,我们可以在实际内容列之前或之后为它们定义静态
    s。我用另一个示例/子问题更新了问题,即not工作(现在可以省略按钮/链接列要求)哦,是的,
    createColumnWithCss
    只是一个本地助手方法,可以使输出文本内容不换行,而是显示一个…来代替。好吧,你说你正在使用带有按钮、链接等的列,但是在
    createColumnWithCss
    方法中,你只创建输出文本列,对吗?我缺少什么?我从来没有见过t他对组件的灵活性要求很好奇。我相信还有第三个选项可以为您提供更大的灵活性,使用和编写您自己的编码器。通过这种方式,您可以用java定义组件的呈现行为,而不是用xhtml,因为xhtml有更多的限制。好吧,我发布的示例来自一个更简单的应用程序选项,因此实际上没有显示链接列和按钮列。正如我所想,我们可能会忽略按钮列和链接列,因为它们通常位于可配置列的最左侧或右侧。因此,我们可以在实际内容列之前或之后为它们定义静态的
    。我用其他不起作用的示例/子问题(您现在可以省略按钮/链接列要求)。哦,是的,
    createColumnWithCss
    只是一个本地帮助器方法,用于使输出文本内容不换行,而是显示一个…来代替。
    public abstract class BaseColumnHandler implements ColumnHandler, Serializable
    {
        // recent order of columns as string, e.g. "active nbr code bank-code ..."
        private String       recentOrder;
    
        private List<Column> boundColumns;
    
        /**
         * The getter for the Facelet c:forEach. (Will reload and parse the recent order on any request from the UI.)
         */
        public List<Column> getBoundColumns()
        {
            if ( this.boundColumns == null )
            {
                List<Column> shownColumns = new ArrayList<Column>();
    
                // parse the string of visible columns as getRecentOrder() loaded it from the DB
                String order = this.getRecentOrder().trim();
                String[] columnIds = StringUtils.split( order, ' ' );
    
                // sub classes must implement newConfigurableColumns()
                List<Column> shownColumns = this.newConfigurableColumns();
    
                for ( String columnId : columnIds )
                {
                    // some filtering going on to filter hidden columns (assume this does what it should)
                    ...
                }
    
                // assign visible columns only
                this.boundColumns = shownColumns;
            }
    
            return this.boundColumns;
        }
    
        /**
         * Creates a new list of all generally configurable columns.
         * 
         * @return
         */
        protected abstract List<Column> newConfigurableColumns();
    
        ...
    }
    
    <c:forEach items="#{depotManagerColumnHandler.boundColumns}"
               var="col">                    
        <p:column id="#{col.id}" binding="#{col}" />
    </c:forEach>
    
    java.lang.IllegalStateException: Component ID content-form:data:employee-employee-status-name has already been found in the view.  
    
    <p:columns value="#{depotManagerColumnHandler.boundColumns}"
               var="col">
        <f:facet name="header">
            <h:outputText value="#{col.headerText}"
                          title="#{col.headerText}" />
        </f:facet>
        <h:outputText value="#{dep[col.property]}" />
    </p:columns>
    
    <p:columns value="#{depotManagerColumnHandler.boundColumns}"
               var="col">
        <p:column id="#{col.id}" binding="#{col}" />
    </p:columns>
    
    Caused by: java.lang.IllegalArgumentException: Empty id attribute is not allowed
        at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:566)
        at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:370)
        at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.assignUniqueId(ComponentTagHandlerDelegateImpl.java:369)
        at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:172)
        at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
        at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
        at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:187)