Javascript - свойства объекта не передаются - PullRequest
0 голосов
/ 23 марта 2011

Я довольно новичок в Javascript и не могу понять, почему следующие свойства объекта не передаются.

Я вызываю объект следующим образом:

var URL = "TABLE=_Products&COLUMNS=price_Qty,Sale&MATCH=internal_Model&ROWS="+itemnum ;
var ITEM = new get_Database_Info(URL) ;

иget_Database_Info:

function get_Database_Info(PARAMS) {
    alert(toString(this));
    var URL = document.location.protocol+'//'+document.location.host+'/Catalog/Tools/ajax_Database_Request.php' ;

    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp=new XMLHttpRequest();
        }
    else{// code for IE6, IE5
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }

    if(!xmlhttp){alert('Error: Cannot send XML request.');}
        xmlhttp.onreadystatechange=function() {

            if (xmlhttp.readyState==4 && xmlhttp.status==200){
                alert(toString(this));
                var RESPONSE = xmlhttp.responseText ;
                RESPONSE = RESPONSE.replace(/^\s+/, '');
                var ARR = RESPONSE.split('||') ;
                ARR.pop() ;
                for(var i=0; i<ARR.length; i++){
                    var temparr1 = ARR[i].split('=') ;
                    var NUM = temparr1[0] ;
                    this[NUM] = new Array() ;
                        var temparr2 =   temparr1[1].split('/|') ;
                        temparr2.shift() ;
                            for(var x=0; x<temparr2.length; x++){

                                var temparr3 = temparr2[x].split('??') ;

                                this[NUM][temparr3[0]] = temparr3[1] ;

                            }
                }

            }
        }

    xmlhttp.open("POST", URL, true);
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlhttp.setRequestHeader("Content-length", PARAMS.length);
    xmlhttp.setRequestHeader("Connection", "close");
    xmlhttp.send(PARAMS);

}

Я проверил, что все свойства находятся в 'this' в области действия get_Database_Info, но они не переносятся обратно в ITEM.

Ответы [ 2 ]

0 голосов
/ 23 марта 2011

Когда вы проверяете содержимое объекта?Запрос является асинхронным, поэтому вам нужно подождать, пока обратный вызов не обработает ответ, прежде чем появятся какие-либо свойства в объекте.

Если вы ищете свойства сразу после создания объекта, они никогда не будут там,Даже если ответ очень быстрый, первый раз, когда обратный вызов может быть запущен, - это когда вы выходите из функции, в которой вы создали объект, поэтому браузер возвращает элемент управления.

0 голосов
/ 23 марта 2011

Рискну предположить, что когда функция, присоединенная к onreadystatechange, запускает, что this больше не присоединяется к объекту, который создается в конструкторе, но, вероятно, присоединяется к глобальному объекту или xmlhttpобъект.Я бы попробовал использовать шаблон var that=this:

function get_Database_Info(PARAMS) {
    alert(toString(this));
    var URL = document.location.protocol+'//'+document.location.host+'/Catalog/Tools/ajax_Database_Request.php' ;

    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp=new XMLHttpRequest();
        }
    else{// code for IE6, IE5
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }

    var that=this; // value of that will be stored in the closure

    if(!xmlhttp){alert('Error: Cannot send XML request.');}
        xmlhttp.onreadystatechange=function() {
            if (xmlhttp.readyState==4 && xmlhttp.status==200){
                alert(toString(that));
                var RESPONSE = xmlhttp.responseText ;
                RESPONSE = RESPONSE.replace(/^\s+/, '');
                var ARR = RESPONSE.split('||') ;
                ARR.pop();
                var arrLength = ARR.length; // always precompute array length
                for(var i=0; i<ARR.length; i++){
                    var temparr1 = ARR[i].split('=') ;
                    var NUM = temparr1[0] ;
                    // that is actually equal to the object that I created
                    // in the constructor.
                    that[NUM] = new Array() ;
                    var temparr2 =   temparr1[1].split('/|') ;
                    temparr2.shift() ;
                    var arrayLength = temparr2.length; // always precompute length
                    for(var x=0; x<arrayLength; x++){
                        var temparr3 = temparr2[x].split('??') ;
                        that[NUM][temparr3[0]] = temparr3[1] ;
                    }
                }
            }
        }

    xmlhttp.open("POST", URL, true);
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlhttp.setRequestHeader("Content-length", PARAMS.length);
    xmlhttp.setRequestHeader("Connection", "close");
    xmlhttp.send(PARAMS);

Кроме того, как отмечено в комментариях, когда вы перебираете значения в массиве для цикла for, вы не должны использовать массив.длина, так как метод length будет вызываться каждый раз через цикл, добавляя много ненужной работы.

Кроме того, как отмечает @Guffa, функция, которая добавляет значения, вызывается асинхронно, поэтому свойства не будут существовать до тех пор, пока не завершится XmlHttpRequest, и это очень опасный анти-шаблон.Я настоятельно советую против этого.Лучше, чтобы ваш конструктор сделал синхронный запрос данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...