【问题标题】:p:datatable not updating rows properlyp:datatable 没有正确更新行
【发布时间】:2019-03-03 04:40:02
【问题描述】:

我在一列中有 p:datatable 和 p:inputSwitch 表示“选定”行。我在 p:inputswitch 上触发 p:ajax 事件,其他行被监听器取消选择,当前行被选中。在我更新数据表的那个事件中,支持 bean 中的所有条目都有一个正确的值,开关打开,但它仍然是红色的。

<h:panelGroup layout="block" styleClass="ui-g-12 refinance" id="cotPanel">

    <p:dataTable id="cot" value="#{cot.cods}" var="offer" reflow="true">
            <p:column width="18%" headerText="OFFER">
                    <p:outputLabel value="#{offer.name}" />
            </p:column>
            <p:column headerText="AAA" width="18%" styleClass="num">
                    <p:outputLabel value="#{of:formatNumberDefaultForLocale(offer.aaa, 'nl_NL')}" />
            </p:column>
            <p:column headerText="BBB" width="18%">
                    <p:outputLabel value="#{offer.bbb}" />
            </p:column>
            <p:column headerText="CCC" width="18%" styleClass="num">
                    <p:outputLabel value="#{of:formatNumberDefaultForLocale(offer.ccc, 'nl_NL')}" />
            </p:column>
            <p:column headerText="DDD" width="18%" styleClass="num">
                    <p:outputLabel value="#{offer.ddd}" />
                        </p:column>
            <p:column headerText="Select" width="10%">
                    <h:panelGroup styleClass="Width100 Flex">
                            <p:inputSwitch value="#{offer.selected}">
                                    <p:ajax event="change" listener="#{cot.onSelectCod(offer)}" process="@this"
                                        update="mainForm:cotPanel" />
                            </p:inputSwitch>
                    </h:panelGroup>
            </p:column>
            <p:column headerText="SELECTED" width="10%">
                    <p:outputLabel value="#{offer.selected}"/>
            </p:column>
    </p:dataTable>
</h:panelGroup>

在支持 bean 监听器中:

public void onSelectCod(Cod entry) {
    if (entry.isSelected()) {
        for (Cod codTemp : cods) {
            if (!entry.equals(codTemp)) {
                codTemp.setSelected(false);
            }
        }
    }else {
        // i dont let it become unselected if click on selected row, it becomes unselected only if it is clicked on another entry
        entry.setSelected(true);
    }
}

数据表中的最后一列显示所有值都是正确的,输入开关在右侧,但它是红色的。我也试图在选择的情况下编写一个“绿色”的风格,否则,否则“红色”,并且我在DOM中看到所有其他行得到正确的类,但选择的行不是。

【问题讨论】:

  • 我看到你有静态的styleClass属性,怎么能切换?
  • 即使我删除它也不会改变。
  • 我的意思是,您的redgreen 类应该在哪里设置为表格行?您不会告诉 JSF 这件事,至少在您在此处提供的代码中是这样。您只需更改 selected 属性值并更新面板。
  • 我删除了它们,因为组件应该允许这样做,对吧?因为我更新了整个数据表。我把它们放在 p:inputSwitch 标签中,比如 styleClass="#{offer.selected ? 'green' : 'red'}"。但什么都没有。
  • 最后这段代码是否更新了 DOM 中 inputSwitch 的类?如果是,则可能是 CSS 问题(样式需要修复)。如果不是,那么这是与 JSF 相关的问题(未正确引用组件或任何验证错误)。如果第二种情况,我猜您的请求到达服务器并且正在处理onSelectCod(正如您在问题中所说的那样),那么您如何引用面板组件肯定有问题。

标签: jsf primefaces datatable


【解决方案1】:

问题在于您在侦听器方法中更改了许多值。当您更新表时,其他开关会发生变化,这会触发其余的侦听器。

相反,您可以使用点击事件而不是更改:

<p:inputSwitch value="#{offer.selected}" styleClass="#{offer.selected ? 'green' : 'red'}">
        <p:ajax event="click" process="@this" listener="#{cot.onSelectCod(offer)" 
            update="mainForm:cotPanel" />
</p:inputSwitch>

这样可以确保侦听器方法仅被用户交互的开关调用。

您还需要稍微重写您的侦听器方法,因为现在应该只使用您感兴趣的对象调用它:

public void onSelectCod(Cod entry) {
    // The entry here is now selected (you set it in the inputSwitch value)
    // So just mark the rest of the entries as unselected
    for (Cod codTemp : cods) {
        if (!entry.equals(codTemp)) {
            codTemp.setSelected(false);
        }
    }
}

【讨论】:

  • 我稍后再试。现在我使用临时对象来保存选定的项目,然后我检查列表中的哪个对象是临时对象,并将选定标志设置为列表中的对象。我认为您对点击事件是正确的。听起来很合理:)。感谢您的帮助..
  • 我之前也用 temp 对象写过其他解决方案。问题是它似乎有点压倒性。只要让听众按照你在问题中所说的方式就可以了;- )
  • 是的,我会尝试点击事件。我讨厌编写冗余代码只是为了“破解”某些东西。
  • 事实上,代码现在变得更简单了! JSF 负责在您与之交互的输入中设置所选值。
  • 没有为 p:inputSwitch 定义点击事件。我明白你的意思。我用方法改变了一些输入......但我注意到的是支持bean中的方法只被调用一次。从我的角度来看,它应该与更改事件一起使用。
猜你喜欢
  • 2017-07-06
  • 1970-01-01
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多