0

我有以下简单的 PrimeFaces 数据表:

<p:dataTable id="list"
             value="#{collisionManager.nodeCollisions}"
             var="cln"
             selection="#{collisionManager.selectedCollisionsArray}"
             rowKey="#{cln.id}"
             rowIndexVar="rowIndex">

    <p:ajax event="rowSelectCheckbox" process="@this" update="@this" />
    <p:ajax event="rowUnselectCheckbox" process="@this" update="@this" />

    <p:ajax event="rowToggle" global="false" />

    <p:column styleClass="row-toggler">
        <p:rowToggler />
    </p:column>

    <p:column selectionMode="multiple" />

    ...

    <p:rowExpansion>
        <h:panelGrid columns="3">
            ... some info about the row
        </h:panelGrid>
    </p:rowExpansion>

</p:dataTable>

如您所见,表格中有一个<p:rowToggler>列和一个多选复选框<p:column selectionMode="multiple" />列。这是一张图片:

在此处输入图像描述

然而,复选框选择的 PF 实现似乎在单击复选框后更新了整个表格,这导致所有当前展开的行扩展再次折叠。

为了解决这个问题(并且由于“CantReplicate”错误http://code.google.com/p/primefaces/issues/detail?id=3794使取消选中所有复选框起作用),我们决定实现多选框我们自己。

    <p:column selectionMode="multiple" />

然后变成:

    <p:column>
        <p:selectBooleanCheckbox value="#{collisionManager.checkedStates[rowIndex]}">
            <p:ajax process="@this"
                    update="@this"
                    listener="#{collisionManager.processCheck}" />
        </p:selectBooleanCheckbox>
    </p:column>

这基本上按预期工作(通过 bean 中的布尔“检查”状态列表)。但是,当前选定的行不会突出显示。

在通过检查操作后更新整个数据表时

            <p:ajax ...
                    update=":collision-form:list"
                    ... >

额外放置时,根据布尔状态正确突出显示相应的行

<p:dataTable id="list"
             ...
             rowStyleClass="#{collisionManager.checkedStates[rowIndex] ? 'ui-state-highlight' : ''}">

在数据表上,但所有当前展开的行扩展在检查操作后被折叠的效果仍然存在。因此,要解决正在折叠的行(由于行切换器无法设置初始展开/折叠状态),更新整个列表似乎不是要走的路。

然后,我有了使用 jQuery 将高亮部分修补到行上的想法。我添加了一个简单的调用oncomplete="collisionTable.selectRow(#{rowIndex});"

<p:column>
    <p:selectBooleanCheckbox value="#{collisionManager.checkedStates[rowIndex]}">
        <p:ajax process="@this"
                update="@this"
                listener="#{collisionManager.processCheck}"
                oncomplete="collisionTable.selectRow(#{rowIndex});" />
    </p:selectBooleanCheckbox>
</p:column>

这基本上突出了相应的行,但是在 DOM 更新后的某个地方调用collisionTable.selectRow(#{rowIndex});失败并出现一些 JS 错误:

a 未定义

萤火虫 说:

“恢复调试器:调试循环期间出错:TypeError:firstViewRangeElement 为空”

a 未定义

1号线

FF 错误控制台说:

类型错误:a 未定义

htps://localhost:8181/blablabla/javax.faces.resource/primefaces.js.xhtml?ln=primefaces

线路:1

PrimeFaces={escapeClientId:function(a){return"#"+a.replace(/:/g,"\:")},....... [极长的最小化代码行]

此错误会导致 JS/AJAX 引擎停止,因此第一个检查操作之外的任何操作都会挂起整个 UI。

为什么这个非常简单的选择调用会失败?怎么了?

Q2

你如何调试这个?

编辑:我还尝试了 oncomplete 在单独的 JS 文件中调用函数。这允许我在 Firebug 中设置断点,但它并没有让我更进一步。我在单步执行时唯一意识到的是,前一个状态而不是检查操作后的状态传递给该方法,并且在处理突出显示整个 selectRow 失败。当前代码:

oncomplete="processChecked( #{collisionManager.checkedStates[rowIndex]}, #{rowIndex} );"

select-row.js 文件:

function processChecked( checkedState, rowIndex )
{
    alert( "Checked state = " + checkedState + ", index = " + rowIndex );

    if ( !checkedState )
    {
        collisionTable.selectRow( rowIndex, true );
    }
    else
    {
        collisionTable.unselectRow( rowIndex, true );
    }
}

请注意,条件是相反的。如果有人知道为什么旧状态会通过,请赐教。

4

0 回答 0