Primefaces' commandLink仅适用于dataTable

时间:2015-07-24 09:42:27

标签: jsf primefaces commandlink

我在p:dataTable中有一个带p:commandLink的列,它有一个paginator。当用户单击commandLink时,会打开一个对话框,显示该行的数据。

datatable html代码:

<p:dataTable id="dtSample" value="#{sessionBean.sampleList}"
    binding="#{requestBean.dtSampleList}"
    paginator="true" paginatorPosition="bottom"
    paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
    rowsPerPageTemplate="#{10,25,50}"
    currentPageReportTemplate="({startRecord} of {totalRecords})"
    var="item" emptyMessage="No entries." rows="10" rowKey="#{item.id}">
    <p:column headerText="Id">
        <p:commandLink id="lnkSample"
            action="#{requestBean.onLinkClick(item)}"
            oncomplete="PF('dlgSample').show();"
            update="@(.dialogClass)">
            <h:outputText value="#{item.id}" />
                        </p:commandLink>
    </p:column>
    <p:column headerText="Code">
        <h:outputText value="#{item.code}" />
    </p:column>
    <p:column headerText="Description">
        <h:outputText value="#{item.descr}" />
    </p:column>
</p:dataTable>

请求bean:

public class RequestBean {

    private SessionBean sessionBean;

    private DataTable dtSampleList;

    public void init() {
        // load samle list
        loadSampleList();
    }

    public String onLinkClick(Sample sample) {
        getSessionBean().setSelectedSample(sample);
        return "success";
    }

    private void loadSampleList() {
        List<Sample> list = new ArrayList<Sample>();

        for (int i = 0; i < 100; i++) {
            Sample tmp = new Sample();
            tmp.setId(new BigDecimal(i + 1));
            tmp.setCode("code" + (i + 1));
            tmp.setDescr("desc" + (i + 1));
            list.add(tmp);
        }
        getSessionBean().setSampleList(list);

    }

// getters and setters

}

会话bean:

public class SessionBean implements Serializable {
    private static final long serialVersionUID = 1L;

    private List<Sample> sampleList;
    private Sample selectedSample;

    // getters and setters

}

对话框html代码:

<p:dialog id="dlgSample" closeOnEscape="true" widgetVar="dlgSample"
                    styleClass="dialogClass" modal="true">
    <p:panelGrid columns="1">
        <h:outputText value="Id: #{sessionBean.selectedSample.id}" />
        <h:outputText value="Code: #{sessionBean.selectedSample.code}" />
        <h:outputText value="Description: #{sessionBean.selectedSample.descr}" />
    </p:panelGrid>
</p:dialog>

当我单击数据表第一页上的链接时,将执行链接操作,并正确刷新显示行数据的对话框。但是,当我移动到数据表的以下任何页面时,单击链接不会刷新对话框中的数据(链接操作未被调用,因此对话框中的数据错误 - selectedSample变量具有旧值)。当然,当我回到数据表的第一页时,命令链接再次起作用(调用操作方法并刷新数据)。

我做错了什么?为什么不在任何数据表页面上调用action方法?

我使用的是Primefaces 5.2。

3 个答案:

答案 0 :(得分:2)

看起来问题出在PF dataTable组件中。缺少firstrows属性,添加后,所有页面上的commandLink都按预期工作。

答案 1 :(得分:1)

  

我做错了什么?为什么不在任何数据表页面上调用action方法?

导致该行为的常见错误是您的state不一致:要处理表单提交,JSF将重新创建与先前请求完全相同的视图,然后应用更改(执行操作) )

如果此新视图现在与提交之前的视图不同,则每个操作都将中止而不会被调用。 (在涉及的元素方面不同。即,如果您的commandLink在提交前为rendered="true",则在rendered="true" - 阶段期间需要APPLY_REQUEST_VALUES

因此,根据您的描述,我会假设您的表后退到第1页,这将从视图中删除第2页上的任何链接并中止其查看操作,因为该元素不再呈现

出于同样的原因,第1页上的链接正常工作,因为即使您的表失去了当前页面的跟踪 - 它将呈现第1页,因此您拥有与之前相同的视图,因此提交工作正常。

您可以通过增加每页的元素数量来轻松验证这一点,并查看从第2页到第1页的每个链接现在都在运行。

但是没有看到整个豆子,我只能假设这一点。为便于测试,请将您的bean设置为@SessionScoped并查看是否可以解析它。

有关更多提示,请参阅此帖:commandButton/commandLink/ajax action/listener method not invoked or input value not updated

答案 2 :(得分:0)

将p:commandLink等组件放入p:dataTable行时,应始终指定

JobParameters

所以,在你的情况下,我会尝试:

process="@this"

这样做,您确定只会处理链接上的点击,并且不会执行任何其他提交。