无法更新Primefaces中p:dataTable(不是整个p:dataTable)中的组件

时间:2012-07-27 03:11:15

标签: jsf primefaces

我在Tomcat 7.0.22.0中使用Primefaces 3.3.1。 我有p:dataTable,里面有p:inputText。 p:dataTable的id是“houseTabID:tabView:form0:table”。这是从HTML源复制粘贴的。我让对话框(在表格dataTable之外)通过p:dataTable中的按钮打开,并且该对话框中的p:commandButton更新了dataTable。

p:commandButton看起来像这样;

<p:commandButton ajax="true" action="#{myBean.setInputText()}"
    value="OK"
    update="#{myBean.getUpdateTarget(0)}"/>

myBean.getUpdateTarget(0)将正确的字符串重新转换为指向目标组件。

我可以通过指定“houseTabID:tabView:form0:table”(意味着myBean.getUpdateTarget(0)返回该字符串)来成功更新整个dataTable。但是我在表中有很多行,所以更新整个表需要更长的时间才能完成,滚动位置被重置,这真的很烦人。这使得我只想更新表中的一行,而不是整数。

所以我首先返回“houseTabID:tabView:form0:table:inputBox”来更新我要更新的p:inputText。在p:dataTable中我有这样的东西;

<p:column headerText="Value"
    width="300" style="height:16px; font-size:9pt;">
    <p:inputText id="inputBox" value="#{myItem.value}"
        style="width:95%; height:11px; font-size:9pt;">
        <f:ajax execute="@this" event="blur" />
    </p:inputText>
</p:column>

结果:没有更新,没有错误日志。我知道“houseTabID:tabView:form0:table:inputBox”将不起作用,因为它没有在表中指定行。因此,通过使用rowIndexVar,我尝试使用“houseTabID:tabView:form0:table:0:inputBox”,使得:0:部分来自rowIndexVar。该字符串是从HTML源复制粘贴的。但不幸的是,我得到了例外。

javax.faces.FacesException: Cannot find component with identifier ":houseTabID:tabView:form0:table:0:inputBox" referenced from "houseTabID:j_idt181:j_idt186".

为什么呢?显然有“houseTabID:tabView:form0:table:0:inputBox”,我在HTML源代码上看到它,我可以使用“houseTabID:tabView:form0:table”更新整个talbe但是使用“houseTabID:tabView:form0”抛出异常:表:0:输入框“?这对我来说没有意义。此外,为什么它不会抛出任何异常或用“houseTabID:tabView:form0:table:inputBox”溢出错误日志?我验证了那个p:commandButton;

的HTML源代码
onclick="PrimeFaces.ab({source:'houseTabID:j_idt190:j_idt195',update:'houseTabID:tabView:form0:table:inputBox',

我绝望地只想更新一行而不是整个p:dataTable。请帮帮我。

2 个答案:

答案 0 :(得分:1)

我找到了解决方案。根据{{​​3}}对话,

position = JQuery(".ui-datatable-scrollable-body").scrollTop();
JQuery(".ui-datatable-scrollable-body").scrollTop(position);

可以做到这一点。看来这是获取和设置p:dataTable的垂直滚动位置的唯一方法。我在打开对话框之前保存了位置,并在从对话框更新p:dataTable后设置了位置。它有效,这就是我想要做的。

但上述方法存在严重问题。该代码从顶部扫描给定的类“.ui-datatable-scrollable-body”,并在第一个找到的位置执行。所以它只适用于一个p:dataTable。幸运的是,我可以提出第二个解决方案。

<script type="text/javascript">
    $ = jQuery;
    var scrollPos;
        function saveScrollPos()
        {
            scrollPos = $("#houseTabID\\:tabView\\:form0\\:table_data").parents(".ui-datatable-scrollable-body").scrollTop();
        }
        function getScrollPos()
        {
            $("#houseTabID\\:tabView\\:form0\\:table_data").parents(".ui-datatable-scrollable-body").scrollTop(scrollPos);
        }
</script>

FireFox中的FireBug帮助我发现有一个componnet id,其中“_data”由Primefaces处理。请看我的问题,我的数据表的id是“table”,有人创建了“table_data”。我可以用上面显示的转义语法指出它,函数parents()导致那个位​​置。它在我的应用中运行良好。

我真的非常感谢stier01发布了他的解决方案,这是我唯一可以在网上找到的解决方案。而且我真的很难过,Primefaces p:dataTable不支持这样一个基本的东西。我知道我们很多人想要在更新时保持p:dataTable的滚动位置。我希望它能在不久的将来得到改善。

答案 1 :(得分:0)

我在我所知道的边缘摇摇欲坠,但我怀疑由于页面构建的时间安排可能会发生这种情况。构建DOM树时,表行尚不存在,因此表外的按钮无法找到对该行的引用(因为它尚不存在)。在构建树并填充数据之后,行就在那里。这就是为什么在页面渲染后你可以查找列id,但不能从表外引用它。

我不确定是否有解决方案。也许您可以在数据表标记中放置一个远程命令来更新它。也许可以在JS中做点什么。