如何通过jee-7中的mdb-> websocket更新数据表单元格? (db pk,clientId映射)

时间:2018-07-03 15:21:28

标签: jsf jms jsf-2.2 java-ee-7 java-websocket

我有一个带分页的jsf-2.2 primefaces数据表。一栏显示网络组件的状态,在表加载时,我通过资源适配器异步查询外部服务。加载数据表后,状态单元将显示为“未知状态”。有时,我会在消息驱动Bean中以json的形式从单个网络组件接收状态包。然后,我想通过网络套接字将此状态发送到浏览器以更新表格单元格。 json状态数据包包含网络组件的主数据库密钥,但是在浏览器的javascript端,我需要数据表单元格的clientIds。 clientId的格式为“ switchTable:swths:2:switchActive”,只是中间的索引有所不同。

我的第一个想法是编写一个facelet并用网络组件的主键覆盖id,但是我认为这不是可行的方法。

是否存在将clientId映射到各个主键的推荐方法?该映射将需要包括会话,因为存在多个具有相同clientId的会话。我要更新在DOM中立即找到document.getElementById并带有状态文本的表格单元格。

1 个答案:

答案 0 :(得分:1)

我想出了两个解决这个有趣问题的方法。

解决方案1 ​​

  • 在其中定义带有“ ID”文本的隐藏表列,
  • 使用JavaScript通过遍历所有行并匹配ID列单元格的“值”来查找数据表的行和单元格

解决方案2

  • 利用JSF2命名空间xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"'以编程方式'设置列单元格元素的html id属性,
  • 使用javascript的document.getElementById函数查找单元格元素

示例

xhtml页面

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui" 
    xmlns:pt="http://xmlns.jcp.org/jsf/passthrough" >

    <f:view contentType="text/html">
        <h:head>
            <h:outputScript library="primefaces" name="jquery/jquery.js" />
        </h:head>

        <h:body>
            <p:dataTable id="dataTable" widgetVar="dataTableWidget" value="#{switchController.switches}" var="switch" paginator="true" rows="5">
                <p:column headerText="id" style="display:none">
                    <h:outputText value="#{switch.id}"/>
                </p:column>
                <p:column headerText="Name">
                    <h:outputText value="#{switch.name}"/>
                </p:column>
                <p:column headerText="status">
                    <h:outputText value="#{switch.status}" pt:id="dataTable:switch:#{switch.id}:status"/>
                </p:column>
            </p:dataTable>

            <p:commandButton value="Change status" type="button" onclick="changeStatusExample()"/>
        </h:body>
    </f:view>
</html>

Backing Bean(仅出于本示例的目的)

public class SwitchController {

    List<Switch> switches;

    @PostConstruct
    public void init() {
        switches = new ArrayList<>();
        for (int i = 1; i < 11; i++) {
            switches.add(new Switch(i, "Switch " + i, "STATUS_UNKNOWN"));
        }
    }

    public List<Switch> getSwitches() {
        return switches;
    }

    public void setSwitches(List<Switch> switches) {
        this.switches = switches;
    }
}

其中Switch是具有idnamestatus字段的POJO。

Javascript

// SOLUTION 1
function getTableCellByIdVer1(switchId, colNumber) {
    //get table rows
    var tableRows = PF('dataTableWidget').tbody[0].childNodes;
    //loop through rows    
    for (i = 0; i < tableRows.length; i++) {
        //get cells of current row
        var cells = tableRows[i].cells;
        //get value of hidden ID column cell
        var id = cells[0].innerText;
        if (id === switchId) {
            return tableRows[i].cells[colNumber];
        }
    }
    return null;
}

// SOLUTION 1
function changeSwitchStatusVer1(changedSwitch) {
    var statusCell = getTableCellByIdVer1(changedSwitch.id, 2);
    if (statusCell) {
        //row exists...now we can change the status
        statusCell.innerText = changedSwitch.status;
    } else {
        console.log('Row with switch id=' + changedSwitch.id + ' not found');
    }
}

// SOLUTION 2
function changeSwitchStatusVer2(changedSwitch) {
    //find cell element by html ID attribute given in xhtml
    var elementId='dataTable:switch:' + changedSwitch.id + ':status';
    var statusCell = document.getElementById(elementId);
    if (statusCell) {
        statusCell.innerText = changedSwitch.status;
    } else {
        console.log('Element with id=' + elementId + ' not found');
    }
}

// EXAMPLE
function changeStatusExample() {
    //simulating situation when websocket pushes info about changed switch to browser page
    // SOLUTION 1
    var changedSwitch = {id: '2', status: 'STATUS_ON'};
    changeSwitchStatusVer1(changedSwitch);

    // SOLUTION 2
    //another switch status changed..using another approach to update table cell
    changedSwitch = {id: '4', status: 'STATUS_OFF'};
    changeSwitchStatusVer2(changedSwitch);
}

重要:请注意,只有(更改的开关)ID属于当前“可见”数据表页面的一部分,这两种解决方案才有效。