【问题标题】:OmniFaces Ajax utility's updateColumn() not updating p:dataTableOmniFaces Ajax 实用程序的 updateColumn() 不更新 p:dataTable
【发布时间】:2012-10-29 19:27:09
【问题描述】:

最近,我关于 OmniFaces Ajax.updateColumn() 的问题得到了以下解答:

How to use OmniFaces Ajax.updateColumn() or Ajax.updateRow() via p:ajax

在这种情况下,dataTable 是 JSF 标准 h:dataTable,效果很好。

现在,在这种情况下,当最终用户通过 p:dataTable 外部存在的 p:calendar 组件选择日期时,我正在尝试更新 PrimeFaces p:dataTable。 p:dataTable xhtml 如下:

<p:dataTable id="flightDataTable" var="flight" 
             value="#{pf_flightController.flightsForOrder}">

    <p:column headerText="Airport" style="text-align: center !important;">
        <p:inputText value="#{flight.airportTx}" maxlength="25" size="10" label="Airport"/>
    </p:column>

    <p:column headerText="Airline" style="text-align: center !important;">
        <p:inputText value="#{flight.airlineTx}" maxlength="25" size="10" label="Airline"/>
    </p:column>

    <p:column headerText="Flight Number" style="text-align: center !important;">
        <p:inputText value="#{flight.flightNumber}" maxlength="8" size="10" label="Flight Number"/>
    </p:column>

    <p:column headerText="Type" style="text-align: center !important;">
        <h:selectOneMenu value="#{flight.flightType}" label="Flight Type">
            <f:selectItem itemValue="#{bundle.DropdownOptionValueArrive}" itemLabel="#{bundle.DropdownOptionLabelArrive}"/>
            <f:selectItem itemValue="#{bundle.DropdownOptionValueDepart}" itemLabel="#{bundle.DropdownOptionLabelDepart}"/>
        </h:selectOneMenu>
    </p:column>

    <p:column headerText="Date" style="text-align: center !important;">
        <h:panelGroup rendered="#{pf_usersController.loggedInViaAndroid == 'N'}">
            <p:calendar value="#{flight.flightDate}" navigator="true"
                        label="Flight Date"
                        pattern="MM/dd/yyyy" size="10">
                <f:convertDateTime pattern="MM/dd/yyyy" />
            </p:calendar>
        </h:panelGroup>
        <h:panelGroup rendered="#{pf_usersController.loggedInViaAndroid == 'Y'}">
            <p:inputText value="#{flight.flightDate}"
                         label="Flight Date" type="date">
                <f:convertDateTime pattern="yyyy-MM-dd" />
            </p:inputText>
        </h:panelGroup>
    </p:column>

    <p:column headerText="Time" style="text-align: center !important;">
        <h:panelGroup rendered="#{pf_usersController.loggedInViaAndroid == 'N'}">
            <pe:timePicker value="#{flight.flightTime}"
                           label="Flight Time" mode="popup"
                           showPeriod="true" style="width: 80px;">
                <f:convertDateTime pattern="hh:mm a" />
            </pe:timePicker>
        </h:panelGroup>
        <h:panelGroup rendered="#{pf_usersController.loggedInViaAndroid == 'Y'}">
            <p:inputText value="#{flight.flightTime}"
                         label="Flight Time" type="time">
                <f:convertDateTime pattern="HH:mm" />
            </p:inputText>
        </h:panelGroup>
    </p:column>

</p:dataTable>

最初和当前正在生产中,p:calendar p:ajax update="..." 更新了“整个”航班 p:dataTable,因此 p:dataTable 中的日期列已成功更新。我知道,我知道,如果它没有坏,那就不要修复它,但是今天我正在修改这段代码和 xhtml,所以我想使用 OmniFaces Ajax 实用程序的 updateColumn() 来只更新“一个”列此 PrimeFaces p:dataTable 的行。

下面是最终用户通过 p:calendar 选择日期时执行的代码片段;这是调用 OmniFaces Ajax 实用程序的 updateColumn() 的代码。

private void updateFlightDateOnAdd() {
    flightController.updateFlightDateOnAdd(current.getTripDateTime());

    UIData flightsDataTable = null;
    try {
        flightsDataTable = (UIData) Components.findComponent(":orderAddForm:flightDataTable");
    } catch (Exception e) {
        System.out.println("pf_OrdersController.updateFlightDateOnAdd(): caught exception on Components.findComponent(...)");
    }
    if (flightsDataTable != null) {
        System.out.println("pf_OrdersController.updateFlightDateOnAdd(): Components.findComponent(...) found " + flightsDataTable.getClientId());
        Ajax.updateColumn(flightsDataTable, 4);
    }
    else {
        System.out.println("pf_OrdersController.updateFlightDateOnAdd(): Components.findComponent(...) returned null");
    }
}

下面是 POJO 的定义:

public class FlightForOrder {
    private Integer flightId;
    private String airportTx, airlineTx, flightNumber;
    private Character flightType;
    private Date flightDate, flightTime;

    public FlightForOrder() {

    }

    public Integer getFlightId() {
        return flightId;
    }

    public void setFlightId(Integer flightId) {
        this.flightId = flightId;
    }

    public String getAirportTx() {
        return airportTx;
    }

    public void setAirportTx(String airportTx) {
        this.airportTx = airportTx;
    }

    public String getAirlineTx() {
        return airlineTx;
    }

    public void setAirlineTx(String airlineTx) {
        this.airlineTx = airlineTx;
    }

    public Date getFlightDate() {
        return flightDate;
    }

    public void setFlightDate(Date flightDate) {
        this.flightDate = flightDate;
    }

    public String getFlightNumber() {
        return flightNumber;
    }

    public void setFlightNumber(String flightNumber) {
        this.flightNumber = flightNumber;
    }

    public Date getFlightTime() {
        return flightTime;
    }

    public void setFlightTime(Date flightTime) {
        this.flightTime = flightTime;
    }

    public Character getFlightType() {
        return flightType;
    }

    public void setFlightType(Character flightType) {
        this.flightType = flightType;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 97 * hash + Objects.hashCode(this.flightId);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final FlightForOrder other = (FlightForOrder) obj;
        if (!Objects.equals(this.flightId, other.flightId)) {
            return false;
        }
        return true;
    }

}

在测试时,服务器日志中显示以下内容:

INFO: pf_OrdersController.updateFlightDateOnAdd(): Components.findComponent(...) found orderAddForm:flightDataTable

所以,这意味着我获得了 PrimeFaces p:dataTable 的良好引用,所以我将 UIData 类型的组件传递给 Ajax.updateColumn()。

最终结果,PrimeFaces 数据表没有被 OmniFaces Ajax 实用程序的 updateColumn() 更新。

我刚刚注释掉了 Ajax.updateColumn(...) 并将 update="..." 重新添加到 p:calendar p:ajax 中,PrimeFaces dataTable 更新成功。

请告知我可能需要做什么来确保通过 Ajax.updateColumn(...) 更新 PrimeFaces 数据表。谢谢。

【问题讨论】:

    标签: ajax jsf primefaces omnifaces


    【解决方案1】:

    更换

    <p:column headerText="Date" style="text-align: center !important;">
        <h:panelGroup rendered="#{pf_usersController.loggedInViaAndroid == 'N'}">
            <p:calendar value="#{flight.flightDate}" navigator="true"
                        label="Flight Date"
                        pattern="MM/dd/yyyy" size="10">
                <f:convertDateTime pattern="MM/dd/yyyy" />
            </p:calendar>
        </h:panelGroup>
        <h:panelGroup rendered="#{pf_usersController.loggedInViaAndroid == 'Y'}">
            <p:inputText value="#{flight.flightDate}"
                         label="Flight Date" type="date">
                <f:convertDateTime pattern="yyyy-MM-dd" />
            </p:inputText>
        </h:panelGroup>
    </p:column>
    

    通过

    <p:column headerText="Date" style="text-align: center !important;">
        <p:calendar value="#{flight.flightDate}" navigator="true"
                    label="Flight Date"
                    pattern="MM/dd/yyyy" size="10"
                    rendered="#{pf_usersController.loggedInViaAndroid == 'N'}">
            <f:convertDateTime pattern="MM/dd/yyyy" />
        </p:calendar>
        <p:inputText value="#{flight.flightDate}"
                     label="Flight Date" type="date"
                     rendered="#{pf_usersController.loggedInViaAndroid == 'Y'}">
            <f:convertDateTime pattern="yyyy-MM-dd" />
        </p:inputText>
    </p:column>
    

    应该修复它。

    说明:Ajax#updateColumn() 仅将 direct 子级的客户端 ID 添加到 PartialViewContext#getRenderIds()。但是,&lt;h:panelGroup&gt; 没有任何最终应出现在结果 HTML 输出中的属性,例如 id,不会将任何内容呈现到 HTML 输出中。因此 JS/Ajax 无法找到 &lt;h:panelGroup&gt; 的 HTML 表示来更新它。

    修复使表格单元格的具体内容改为 direct 子级,这样 JS/Ajax 将能够定位和替换它们。另一种方法是为这些面板组提供具体的id,但这在此构造中是不必要的。

    【讨论】:

    • 像往常一样,你是对的,BalusC!我正在向你学习的另一件事是我在学习的过程中学习。断断续续地,我使用 h:panelGroup,有时我在这种类型的 xhtml 中不使用 h:panelGroup。有时,我只是将 render="..." 添加到组件中,有时,我将多个组件包装在 h:panelGroup render="..." 中。感谢您的回答、解释和 OmniFaces!
    • 还有一点,这个 Ajax.updateColumn() 比 p:ajax update="..." 执行得更好。当我在 p:ajax update="..." 中包含 dataTable 时,除了日期列之外,所有列都丢失了当前值。为什么?好问题,但是 OmniFaces 可以通过 Ajax 实用程序的 updateColumn() 进行救援!!!
    猜你喜欢
    • 2012-09-13
    • 2012-11-29
    • 2012-12-29
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    相关资源
    最近更新 更多