JSF 2.0 无法从 primefaces 呈现对话框

Posted

技术标签:

【中文标题】JSF 2.0 无法从 primefaces 呈现对话框【英文标题】:JSF 2.0 can't render dialog from primefaces 【发布时间】:2011-07-26 06:32:14 【问题描述】:

最近我在使用 primefaces 组件时遇到了很多问题,我不知道为什么。我使用 glassfishV3.0,我的 primefaces 版本是 2.2.1 我现在的问题是,当我单击表格行时,我无法渲染primefaces 的p:dialog。我完全按照他们的例子做的:http://www.primefaces.org/showcase/ui/datatableComplex.jsf

我认为我的问题与某些配置有关,因为我在使用其他 primefaces 组件时也遇到了问题。有人可以帮我一把,告诉我我缺少什么才能毫无问题地使用像这样的primefaces组件吗? 代码如下:

JSF:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:p="http://primefaces.prime.com.tr/ui">
    <ui:composition template="WEB-INF/templates/BasicTemplate.xhtml">
<ui:define name="resultsForm">
<h:form enctype="multipart/form-data">
    <h:inputText id="search" value="" /><h:commandButton value="search"/>               
<p:dataTable var="garbage" value="#resultsController.allGarbage"  dynamic="true" paginator="true" paginatorPosition="bottom" rows="10"  
             paginatorTemplate="CurrentPageReport  FirstPageLink PreviousPageLink  PageLinks NextPageLink LastPageLink RowsPerPageDropdown"  
             rowsPerPageTemplate="5,10,15" selection="#resultsController.garbage" selectionMode="single"  
            onRowSelectUpdate="display" onRowSelectComplete="fileDialog.show()">            

            <p:column sortBy="#garbage.filename" parser="string" filterBy="#garbage.filename" filterMatchMode="startsWith">  
            <f:facet name="header">  
            <h:outputText value="Filename" />  
            </f:facet>  
            <h:outputText value="#garbage.filename" />
             </p:column> 

            <p:column filterBy="#garbage.description" filterMatchMode="contains">  
            <f:facet name="header">  
            <h:outputText value="Description" />  
            </f:facet>  
            <h:outputText value="#garbage.description" />  
             </p:column> 

            <p:column sortBy="#garbage.uploadDate" parser="string">  
            <f:facet name="header">  
            <h:outputText value="Upload date" />  
            </f:facet>  
            <h:outputText value="#garbage.uploadDate" /> 
             </p:column>                
    </p:dataTable> 

    <p:dialog header="Modal Dialog" widgetVar="fileDialog" modal="true" >    

    <h:panelGrid id="display" columns="2" cellpadding="4">  
        <h:outputText value="FileName:" />  
        <h:outputText value="#garbage.filename" />  

        <h:outputText value="Upload date:" />  
        <h:outputText value="#garbage.uploadDate" />  

        <h:outputText value="Description" />  
        <h:outputText value="#garbage.description" /> 
    </h:panelGrid>           

    </p:dialog> 

    </h:form>
</ui:define>
    </ui:composition>

    </html>

托管 bean

@ManagedBean
@ViewScoped
public class ResultsController implements Serializable

@EJB
private ISearchEJB searchEJB;

private Garbage garbage;

public List<Garbage> getAllGarbage() 

    List<Garbage> tmpGarbage = new ArrayList<Garbage>();
    for(Garbage g :searchEJB.findAllGarbage()) 
        tmpGarbage.add(g);
    
    return tmpGarbage;


public Garbage getGarbage() 
    return garbage;


public void setGarbage(Garbage garbage) 
    this.garbage = garbage;
   

之前的 JSF 是我在这个模板中使用的复合页面

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html">
      <h:head>
      <title>title</title>
      <script type="text/javascript">
       PrimeFaces.widget.Uploader.prototype._createPostParams = function() 
       var b = ;
         b[PrimeFaces.PARTIAL_REQUEST_PARAM] = true;
       b[PrimeFaces.PARTIAL_PROCESS_PARAM] = this.id;
       b[PrimeFaces.PARTIAL_SOURCE_PARAM] = this.id;
       b[PrimeFaces.VIEW_STATE] = PrimeFaces.ajax.AjaxUtils.encodeViewState();
       if (this.cfg.update) 
         b[PrimeFaces.PARTIAL_UPDATE_PARAM] = this.cfg.update
        
        var a = PrimeFaces.getCookie("JSESSIONID");
        if (this.cfg.script.indexOf("jsessionid") == -1) 
        paramIndex = this.cfg.script.indexOf('?');
          if (paramIndex != -1) 
           this.cfg.script = this.cfg.script.substring(0, paramIndex)
           + ";jsessionid=" + a
           + this.cfg.script.substring(paramIndex);
       else 
         this.cfg.script = this.cfg.script + ";jsessionid=" + a;
       
       
      b['cid'] = "#javax.enterprise.context.conversation.id";
     return b;
      ;
     PrimeFaces.widget.Uploader.prototype.createPostParams =                  PrimeFaces.widget.Uploader.prototype._createPostParams;
     </script>
     <script type="text/javascript" src="/ primefaces_resource/2.1/yui/datasource/datasource-min.js"></script> 
     <script type="text/javascript"  src="/primefaces_resource/2.1/primefaces/paginator/paginator.js"></script> 
     <script type="text/javascript" src="/primefaces_resource/2.1/yui/datatable/datatable-min.js"></script> 
     <script type="text/javascript" src="/primefaces_resource/2.1/primefaces/datatable/datatable.js"></script> 
     <script type="text/javascript" src="/primefaces_resource/2.1/yui/swf/swf-min.js"></script> 
     <script type="text/javascript" src="/primefaces_resource/2.1/yui/charts/charts-min.js"></script> 
     <script type="text/javascript" src="/primefaces_resource/2.1/primefaces/charts/charts.js"></script>
     </h:head>

     <body> 
 <ui:insert name="resultsForm"/>
     </body>
     </html>

我的 web.xml 配置

    <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/pages/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
    <welcome-file>pages/index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>org.primefaces.resource.ResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/primefaces_resource/*</url-pattern>
</servlet-mapping> 
    <filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter
    </filter-class>        
</filter>
<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

在上面的表 i 中一切都有效,只是 sortBy 函数和 p:dialog 不起作用。 这是刷新页面时在 Eclipse 控制台上显示的消息:

严重:第 1:61 行在字符 ';' 处没有可行的替代方案

我不明白这是什么意思,我认为我有某种配置问题,而不是语法错误。如果有人能帮我解决这个问题,我会很高兴。

【问题讨论】:

关于对话框,与 primefaces 展示的唯一区别是代码中缺少 rowSelectListener。也许这是进一步调查的起点。或者尝试使用 commandLink 从表格外部调用对话框以检查它是否完全显示。 是的,我可以使用如下按钮从表格外部调用对话框: 可以,但是有什么问题,为什么当我点击表格中的一行时它不起作用? 尝试添加一个rowSelectListener并检查是否被调用。 不,它没有用,我试过这个:rowSelectListener="#fileDialog.show()" 可能是其他一些选项令人不安吗?: selection="#resultsController.garbage" selectionMode ="single" update="display" rowSelectListener="#fileDialog.show()" 尝试将p:dialog 放在您的`p:dataTable' 的h:form 之外,看看是否能解决问题?如果没有,我将尝试在我的计算机上重现您的问题 【参考方案1】:

嗯,我创建了您的代码的简化版本,我的工作完美。每次单击该行时,都会弹出我的对话框。尝试在一个新项目上运行此代码,看看它是否有效。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <link rel="stylesheet" href="themes/blitzer/skin.css?$config.startupTime" type="text/css"/>

    </h:head>
    <h:body>
        <h:form enctype="multipart/form-data">
            <p:dataTable var="item" value="#myBean.myList"  dynamic="true" paginator="true" paginatorPosition="bottom" rows="10"
                         paginatorTemplate="CurrentPageReport  FirstPageLink PreviousPageLink  PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
                         rowsPerPageTemplate="5,10,15" selection="#myBean.selectedResult" selectionMode="single"
                         onRowSelectUpdate="display" onRowSelectComplete="fileDialog.show()">
                <p:column>
                    <h:outputText value="#item"/>
                </p:column>
            </p:dataTable>            
        </h:form>
        <p:dialog widgetVar="fileDialog">
            <h:outputText value="Dialog open"/>
        </p:dialog>
    </h:body>
</html>

这是我的豆子

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.test;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

/**
 *
 * @author KingdomHeart
 */
@ManagedBean
@ViewScoped
public class MyBean 

    private List<String> myList;

    private String selectedResult;

    public MyBean() 
    

    @PostConstruct
    public void init()
        myList = new ArrayList<String>();
        myList.add("Test1");
        myList.add("Test2");
        myList.add("Test3");
        myList.add("Test4");
        myList.add("Test5");
    

    public List<String> getMyList() 
        return myList;
    

    public void setMyList(List<String> myList) 
        this.myList = myList;
    

    public String getSelectedResult() 
        return selectedResult;
    

    public void setSelectedResult(String selectedResult) 
        this.selectedResult = selectedResult;
        

由 sfrj 更新

正如您所见,我的不止一行是黄色的,这不应该是这样的。 selectionMode="single" 无法正常工作。

Harry 更新

这里是如何将日期类型转换为字符串

public String formatDate(Date date) 
    if (date != null) 
        SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy");
        return sdf.format(date);
    
    return null;

那么你的 JSF 会是这样的

h:outputText value="#resultsController.formatDate(garbage.uploadDate)" /> 

sfrj 更新 2

这是全新的 JSF 页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:p="http://primefaces.prime.com.tr/ui">
     <ui:composition template="WEB-INF/templates/BasicTemplate.xhtml">
<ui:define name="resultsForm2">
<h:form enctype="multipart/form-data">              
    <p:dataTable var="garbage" value="#resultsController.allGarbage"  dynamic="true" paginator="true" paginatorPosition="bottom" rows="10"
                     paginatorTemplate="CurrentPageReport  FirstPageLink PreviousPageLink  PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
                     rowsPerPageTemplate="5,10,15" selection="#resultsController.selectedGarbage" selectionMode="single"
                     rowSelectListener="#resultsController.rowIsSelected">
            <p:column>
                <h:outputText value="#garbage.filename"/>
            </p:column>
        </p:dataTable>            
    </h:form>
    <p:dialog widgetVar="fileDialog">
        <h:outputText value="Dialog open"/>
    </p:dialog>   
</ui:define>
    </ui:composition>
    </html>

【讨论】:

我做到了,是的,它工作正常,你是对的。但我不明白为什么在另一个项目中不起作用,它几乎是一样的。是不是有什么冲突?你提到的关于“fileDialog.show()”的事情,我怎么能在支持 bean 中编写这样的函数?如何从中访问对话框并告诉它显示? 我刚试过这个:public void onRowSelect(SelectEvent event)garbage = (Garbage)event.getObject(); 在我的托管 bean 上,我这样称呼它:rowSelectListener="#resultsController .onRowSelect" 但似乎不起作用:( @sfrj:不断敲打不起作用的东西不是一个好主意。我想让你做的是:现在你知道我的例子是有效的,所以我们将从那里开始。从我的代码中,开始将您的组件放入其中(尽管一次一个组件)。每次放入组件时,重新部署并查看对话框是否仍然显示。这样我们可以缩小问题的范围,同时,我会尝试再次查看您的代码。 你说得对,这就是我明天早上要做的事情。我将创建一个全新的页面并开始逐个添加。另外,我只是要对您的帖子进行更新,以向您展示比较两者的打印屏幕。我还注意到在我的情况下,由于某种原因,选项 selectionMode="single" 看起来不起作用。查看更新。无论如何,非常感谢你,我希望明天早上我有更多的运气:) @sfrj:我在 p:column 上注意到,你有一个 parser="string"。我不认为 p:column 有那个属性。

以上是关于JSF 2.0 无法从 primefaces 呈现对话框的主要内容,如果未能解决你的问题,请参考以下文章

在 PrimeFaces 3.4 JSF 2.0 中按 id 查找组件

使用 JSF 2.0 和 Primefaces 设置项目

Spring Security + JSF 2.0 + Primefaces + Hibernate 配置

JSF 页面元素无法从具有动作属性的支持 bean 触发方法。(JSF2.0 + primefaces)

如何在 JSF 2.0 中使用表单重新呈现页面的一部分?

JSF 2.0 更新 primefaces 对话框第一次不起作用