表单中的多个命令按钮在Primefaces DataTable中无法正常工作

时间:2017-08-27 15:24:05

标签: jsf primefaces datatable

我有一个DataTable,每行都有一个commandButton来下载特定文件。

<p:dataTable value="#{studentClassroomBean.papers}" var="paper" id="paperDT"
             paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
             paginator="true" rows="10" rowsPerPageTemplate="5,10,15" paginatorPosition="bottom"
             rowKey="#{paper.paperId}" style="margin: 20px 20px 20px 20px;"
             selection="#{studentClassroomBean.selectedPapers}">
    <p:column selectionMode="multiple" style="width: 16px; text-align:center;"/>

    <p:column headerText="Download" style="text-align: center; width: 80px">
        <h:form>
            <p:commandButton icon="fa fa-download" actionListener="#{studentClassroomBean.downloadPaper}" 
                             ajax="false">
                <f:param name="paperId" value="#{paper.paperId}"/>
                <p:fileDownload value="#{studentClassroomBean.downloadFile}"/>
            </p:commandButton>
        </h:form>
    </p:column>

    <f:facet name="footer">
        <p:commandButton value="Download Papers" icon="fa fa-download" ajax="false"
                         actionListener="#{studentClassroomBean.batchDownload}" process="paperDT">
            <p:fileDownload value="#{studentClassroomBean.downloadZip}"/>
        </p:commandButton>
    </f:facet>
</p:dataTable>

如果我只用表单包裹commandButton而不是包装整个dataTable,那么这种方法很有效。如果我用表单包装整个dataTable的问题是,无论你点击哪个按钮,managedBean中<f:param name="paperId" value="#{paper.paperId}"/>的值总是相同的,就像它没有更新托管中的值一样单击第一次下载按钮后的bean。这是ManagedBean中的downloadPaper函数

public void downloadPaper() throws IOException
{
    Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
    Paper selectedPaper = paperService.findByPaperId(params.get("paperId"));
    String fullPath = DIRECTORY + selectedPaper.getFileName();
    String contentType = FacesContext.getCurrentInstance().getExternalContext().getMimeType(fullPath);
    String fileName = selectedPaper.getTitle() + "." + FilenameUtils.getExtension(fullPath);
    InputStream input = new FileInputStream(new File(fullPath));
    downloadFile = new DefaultStreamedContent(input, contentType, fileName);
}

此问题导致用户希望下载的论文始终与他/她下载的第一篇论文相同。例如,我点击第一行的下载按钮,然后点击第二行的下载按钮,但下载的文件仍然与前一行相同。我能知道为什么吗?怎么解决这个?我必须用表单包装整个dataTable,以使selection起作用。关于如何解决这场冲突的任何想法?抱歉我的英文。

1 个答案:

答案 0 :(得分:1)

使用另一种方法将参数传递给bean解决了这个问题 而不是使用<f:param>标记

传递参数
<p:column headerText="Download" style="text-align: center; width: 80px">
    <p:commandButton icon="fa fa-download" actionListener="#{studentClassroomBean.downloadPaper}" 
             ajax="false">
        <f:param name="paperId" value="#{paper.paperId}"/>
        <p:fileDownload value="#{studentClassroomBean.downloadFile}"/>
    </p:commandButton>
</p:column>

我把它更改为:

<p:column headerText="Download" style="text-align: center; width: 80px">
    <p:commandButton icon="fa fa-download" actionListener="#{studentClassroomBean.downloadPaper(paper.paperId)}" 
                     ajax="false">
        <p:fileDownload value="#{studentClassroomBean.downloadFile}"/>
    </p:commandButton>
</p:column>

并在托管bean中捕获参数,如下所示:

public void downloadPaper(String paperId) throws IOException
{
    Paper selectedPaper = paperService.findByPaperId(paperId);
    String fullPath = DIRECTORY + selectedPaper.getFileName();
    String contentType = FacesContext.getCurrentInstance().getExternalContext().getMimeType(fullPath);
    String fileName = selectedPaper.getTitle() + "." + FilenameUtils.getExtension(fullPath);
    InputStream input = new FileInputStream(new File(fullPath));
    downloadFile = new DefaultStreamedContent(input, contentType, fileName);
}

不知道诀窍在哪里,但它确实有效。希望它可以帮助一些人