1

我正在使用一些第三方连接监控代码( Denis Radin 的Online JS),它与我的页面上的导航元素有交互,我根本不明白。我希望有人可以阐明可能的原因,以便我可以更好地纠正问题。

当 Javascript 代码到位时,我有一个 PrimeFaces commandButton 元素开始间歇性地失败;有时它会将我带到我想要的页面,有时它什么也不做。

    <p:commandButton
        icon="icon-back"
        value="#{appMsgs['button.back.to.inbox']}"
        rendered="#{viewBean.back}"
        actionListener="#{controllerBean.selectState}"
        update=":frmMain:mainContent" />

我还有一个带有 rowSelect 侦听器的 PrimeFaces 数据表,有时单击该侦听器会将我带到错误的页面。

    <p:dataTable
        id="widgets"
        value="#{cc.attrs.widgetList}"
        var="widget"
        widgetVar="widgetTable"
        rowKey="#{widget.widgetId}"
        selectionMode="single"
        <p:ajax
            event="rowSelect"
            listener="#{controllerBean.handleWidget}"
            update=":frmMain:mainContent"
            onstart="widgetTable.clearSelection()"
            process=":frmMain:txtInputTimeElapsed :frmMain:txtInputTimeRemaining :frmMain:mainContent" />
    ...
    </p:dataTable>

麻烦的 Javascript 代码如下所示。(澄清一下,当此代码不存在时,该页面确实可以正常工作。)它以 5 秒的间隔 ping 服务器;如果它无法连接,它会显示一个禁用页面并停止计时器的小部件(假设计时器正在运行)。当连接恢复时,它会重新启动计时器并让用户再次访问该页面。是否有人对让我陷入困境的互动有任何可能的理论/建议?(当然,如果您还可以建议如何更正它,则奖励积分/闪亮的复选标记,但在这一点上,我会更好地理解我要解决的问题。)

除了麻烦的导航交互之外,Javascript 代码在其他方面都可以完美运行。


编辑:根据 BalusC 的评论,我用jQuery 实现 替换了旧版本,这导致了一些改进;commandButton 现在可以可靠地工作,但 rowSelect 侦听器仍然容易脱落并将我带到错误的页面。

我包括了新代码,因为它更加简洁。原始的 Javascript 代码在帖子的底部。


编辑 2: 绝对是 e.ajax 调用让我感到困扰。如果我转到带有 dataTable 对象的页面,等待 e.ajax 调用触发,然后单击一行,我总是会去错误的地方。

添加async:false到 ajax 调用不仅不起作用,还会完全破坏导航;dataTable 中的行突然不再可选择。

那么,有人对为什么 ajax 和 PrimeFaces 不能很好地相互配合以及我如何纠正它有任何建议吗?

新的 jQuery 代码:

        (function(e){

            e.fn.checknet=function(config){
                function connectionLost(){
                    wdgNoConnection.show();
                    if(#{bizSimViewBean.started}) {
                        pauseTimer();
                    }
                }
                function connectionExtablished(){
                    wdgNoConnection.hide();
                    if(#{bizSimViewBean.started}) {
                        startTimer();
                    }
                }
                function checkConnection(url){
                    e.ajax({
                        url:url,
                        cache:false,
                        success:function(){
                            if (!window.checknet.conIsActive) {
                                window.checknet.statusChange = true;
                            }
                            window.checknet.conIsActive=true
                        },
                        error:function(){
                            if (window.checknet.conIsActive) {
                                window.checknet.statusChange = true;
                            }
                            window.checknet.conIsActive=false
                        },
                        complete:function(){
                            if (window.checknet.statusChange) {
                                if(window.checknet.conIsActive){
                                    connectionExtablished()
                                }
                                else{
                                    connectionLost()
                                }
                                window.checknet.statusChange = false;
                            }
                        }
                    })
                    setTimeout(
                        function(){checkConnection(window.checknet.config.checkURL)},
                        window.checknet.config.checkInterval
                    )
                }
                if(typeof t==="undefined"){
                    var t={}
                }
                if(typeof config.checkInterval==="undefined"){
                    t.checkInterval=5e3
                }
                if(typeof config.checkURL==="undefined"){
                    t.checkURL=window.location
                }
                else if(config.checkURL.indexOf("http")===-1){
                    t.checkURL="http://"+t.checkURL
                }
                checkConnection(config.checkURL)
            }
        })(jQuery);

        $(document).ready(function(){
            window.checknet={};
            window.checknet.config={};
            $.fn.checknet(window.checknet.config);
        });

旧的非 jQuery 代码:

        (function (w){
            w.internetConnection = w.internetConnection || {};

            w.internetConnection.addEvent = function(obj, type, callback){
                if (window.attachEvent){
                    obj.attachEvent('on' + type, callback);
                } else {
                    obj.addEventListener(type, callback);
                }   
            };

            var xmlhttp = new XMLHttpRequest();

            w.internetConnection.isXMLHttp = function(){
                return "withCredentials" in xmlhttp;
            };

            w.internetConnection.isXDomain = function(){
                return typeof XDomainRequest != "undefined";   
            };

            //For IE we use XDomainRequest and sometimes it uses a bit different logic, so adding decorator for this
            w.internetConnection.XDomainLogic = {
                init: function(){
                    xmlhttp = new XDomainRequest();
                    xmlhttp.onerror = function(){
                        xmlhttp.status = 404;
                        w.internetConnection.processXmlhttpStatus();
                    };
                    xmlhttp.ontimeout = function(){
                        xmlhttp.status = 404;
                        w.internetConnection.processXmlhttpStatus();
                    };
                },
                onInternetAsyncStatus: function(){
                    try {
                        xmlhttp.status = 200;
                        w.internetConnection.processXmlhttpStatus();
                    } catch(err){
                        w.internetConnection.fireHandlerDependOnStatus(false);
                        w.onLine = false;
                    }
                },
                checkConnectionWithRequest: function(async){
                    xmlhttp.onload = w.internetConnection.logic.onInternetAsyncStatus;

                    var url = w.onLineCheckURL();

                    xmlhttp.open("GET", url);
                    xmlhttp.send();
                }
            };

            //Another case for decoration is XMLHttpRequest
            w.internetConnection.XMLHttpLogic = {
                init: function(){

                },
                onInternetAsyncStatus: function(){
                    if (xmlhttp.readyState === 4){
                        try {
                            w.internetConnection.processXmlhttpStatus();
                        } catch(err){
                            w.internetConnection.fireHandlerDependOnStatus(false);
                            w.onLine = false;
                        }
                    }
                },
                checkConnectionWithRequest: function(async){
                    if (async) {
                        xmlhttp.onreadystatechange = w.internetConnection.logic.onInternetAsyncStatus;
                    } else {
                        xmlhttp.onreadystatechange = undefined;
                    }

                    var url = w.onLineCheckURL();
                    xmlhttp.open("HEAD", url, async);    
                    xmlhttp.send();

                    if (async === false) {
                        w.internetConnection.processXmlhttpStatus();
                        return w.onLine;
                    }    
                }
            };

            if (w.internetConnection.isXDomain()) {
                w.internetConnection.logic = w.internetConnection.XDomainLogic;
            } else {
                w.internetConnection.logic = w.internetConnection.XMLHttpLogic;
            }

            w.internetConnection.logic.init();

            w.internetConnection.processXmlhttpStatus = function(){
                var tempOnLine = w.internetConnection.verifyStatus(xmlhttp.status);
                w.internetConnection.fireHandlerDependOnStatus(tempOnLine);
                w.onLine = tempOnLine;  
            };

            w.internetConnection.verifyStatus = function(status){
                return ( status >= 200 && status < 300 || status === 304 );  
            };

            w.internetConnection.fireHandlerDependOnStatus = function (newStatus){
                if (newStatus === true && w.onLineHandler !== undefined && (w.onLine !== true || w.internetConnection.handlerFired === false)){
                    w.onLineHandler();  
                }
                if (newStatus === false && w.offLineHandler !== undefined && (w.onLine !== false || w.internetConnection.handlerFired === false)){
                    w.offLineHandler(); 
                }
                w.internetConnection.handlerFired = true;
            };

            w.internetConnection.startCheck = function (){
                setInterval("window.internetConnection.logic.checkConnectionWithRequest(true)",w.onLineCheckTimeout);    
            };

            w.internetConnection.stopCheck = function (){
                clearInterval("window.internetConnection.logic.checkConnectionWithRequest(true)",w.onLineCheckTimeout);  
            };

            w.checkOnLine = function(){
                w.internetConnection.logic.checkConnectionWithRequest(false);
            };

            w.onLineCheckURL = function(){
                return window.location.href;
            };

            w.onLineCheckTimeout = 5000;
            w.checkOnLine();
            w.internetConnection.startCheck();
            w.internetConnection.handlerFired = false;

            w.internetConnection.addEvent(w, 'load', function(){
                w.internetConnection.fireHandlerDependOnStatus(w.onLine);   
            });

            w.internetConnection.addEvent(w, 'online', function(){
                window.internetConnection.logic.checkConnectionWithRequest(true);
            });
            w.internetConnection.addEvent(w, 'offline', function(){
                window.internetConnection.logic.checkConnectionWithRequest(true);
            });
        })(window);

        var offline = false;
        window.onLineHandler = function(){
            if (offline) {
                wdgNoConnection.hide();
                if(#{bizSimViewBean.started}) {
                    startTimer();
                }
            }
            offline = false;
        };
        window.offLineHandler = function(){
            if (!offline) {
                wdgNoConnection.show();
                if(#{bizSimViewBean.started}) {
                    pauseTimer();
                }
            }
            offline = true;
        };
4

1 回答 1

3

啊哈!

这是 ajax 调用——特别是对 window.location 的 ajax 调用。这与支持 bean 的状态(或那个附近的东西)有关,导致导航混乱。

因此,如果任何其他绝望的灵魂遇到了这个问题,请将 ajax 指向其他地方。

于 2013-01-31T21:45:21.630 回答