Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   вопрос по jSon + Ajax (https://javascript.ru/forum/events/5321-vopros-po-json-ajax.html)

Beck 04.10.2009 19:52

вопрос по jSon + Ajax
 
У меня к эвенту привязан ajax запрос.

Как получить ответ в виде массива, а не строки?
Возможно ли вообще?

На данный момент парсить прилетевшую строку единственный вариант для меня.

Заранее спасибо.

Kolyaj 04.10.2009 20:10

По протоколу http можно передавать только строки. JSON

Beck 04.10.2009 20:13

Ясно, тогда остается только парсить строку.
Не подскажете, как в яваскрипте удалять последнюю ячейку в массиве?

Kolyaj 04.10.2009 20:27

Цитата:

Сообщение от Beck
Ясно, тогда остается только парсить строку.

Это нормально, через сеть можно передавать только строки, и их приходится парсить. Так везде, если вы этого не видите, это не значит, что этого нет.

Цитата:

Сообщение от Beck
Не подскажете, как в яваскрипте удалять последнюю ячейку в массиве?

http://javascript.ru/Array/pop

Beck 04.10.2009 21:31

Большое спасибо.

Beck 04.10.2009 23:10

Еще вопросик небольшой. Какая альтернатива php функции in_array в яваскрипте?

Kolyaj 04.10.2009 23:14

Метод indexOf у массивов, но он отсутствует в IE, но его можно там создать.

Beck 05.10.2009 02:03

var i = 0;
	while(i < m['mcount']) {
		for(var i2=0;i2 < all_lat.length;i2++){
			if(m['lat'][i] == all_lat[i2]){
				m['lat'][i].splice(i2,1);
				m['lng'][i].splice(i2,1);
			}
		}
		i++;
	}


Пишет ошибку:
m.lat[i].splice is not a function



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

Kolyaj 05.10.2009 08:25

Цитата:

Сообщение от Beck
m.lat[i].splice is not a function

Ну значит m.lat[i] не массив.

x-yuri 05.10.2009 12:16

Цитата:

Сообщение от Beck
Как получить ответ в виде массива, а не строки?
Возможно ли вообще?

если есть, на стороне php можно воспользоваться json_encode. А на стороне js: eval( '('+s+')' );

Beck 05.10.2009 14:46

Цитата:

Сообщение от x-yuri (Сообщение 31724)
если есть, на стороне php можно воспользоваться json_encode. А на стороне js: eval( '('+s+')' );

Есть, попробую. Спасибо. :)

Beck 05.10.2009 15:03

Цитата:

Сообщение от Kolyaj (Сообщение 31700)
Ну значит m.lat[i] не массив.

if(m['mcount'] > 0) {
		while(i < m['mcount']) {
			for(var i2=0;i2 < all_lat.length;i2++){
				console.log(m);
				if(m['lat'].length > 0) {
					if(m['lat'][i] == all_lat[i2]){
						m['lat'][i].splice(i,1);
						m['lng'][i].splice(i,1);
					}
				}
			}
			i++;
		}
	}


Object lat=[2] lng=[2] mcount=2


Lat:
["56.50097598931345", "56.49983904637648" 0=56.50097598931345 1=56.49983904637648]

Beck 05.10.2009 15:05

Что самое интересное, ошибка происходит, только на первом эвенте, а потом все повторы проходят без ошибок.

x-yuri 05.10.2009 15:26

Цитата:

Сообщение от Beck
Object lat=[2] lng=[2] mcount=2

ну так, m['lat'] - не массив, а тем более m['lat'][i]

Beck 05.10.2009 15:52

А как тогда правильно обратиться к данным?

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

var m = {"lat": lat,"lng": lng,"mcount": data1[2]};

Как правильно создать многомерный массив в моем случае, если lat и lng возможно будут массивами в прилетевшем ответе.

var m = [];
			m.push(lat);
			m.push(lng);
			m.push(data1[2]);


Так будет правильно?

*Вроде разобрался*
Только не понял, как обращаться к данным ассоциативного массива/объекта.

x-yuri 05.10.2009 16:27

Цитата:

Сообщение от x-yuri
ну так, m['lat'] - не массив, а тем более m['lat'][i]

или просто не видно, что он из себя представляет

Цитата:

Сообщение от Beck
Еще бы узнать, как ассоциативный массив создавать и как обращаться к его данным

var a = {a: 1, b: 2};
alert(a.a);

Beck 05.10.2009 17:23

Цитата:

Сообщение от x-yuri (Сообщение 31750)
или просто не видно, что он из себя представляет


var a = {a: 1, b: 2};
alert(a.a);

А в случае многомерного?

x-yuri 05.10.2009 18:06

try to guess ;)

Beck 05.10.2009 19:37

var allmakers = [];
var all_lat = [];
var all_lng = [];
var all_lat_length = 0;
var all_lng_length = 0;

function insert_marker(lat,lng){
	all_lat.push(lat);
	all_lng.push(lng);
	all_lat_length++;
	all_lng_length++;
	var mark = new GMarker(new GLatLng(lat,lng)); 
	allmakers.push(mark);
}

function process_markers(m) {
	console.log(allmakers);
	if(all_lat_length > 0) {
	var i = 0;
	var rounds = m[2];
	
	if(m[2] > 1) {
		while(i < rounds){
		var i2 = 0;
		while(i2 < all_lat_length) {
			if(m[0][i] == all_lat[i2]){m[0].splice(i,1);m[1].splice(i,1);m[2]--;}
			i2++;
			}
		i++;
		}
	}
	else {
		var i2 = 0;
		while(i2 < all_lat_length) {
			if(m[0] == all_lat[i2]){m[0] = '';m[1] = '';m[2]--;}
			i2++;
			}			
		}
	}	
	
		
	console.log(m[2]);	
	if(m[2] > 1) {	var i = 0;while(i < m[2]){insert_marker(m[0][i],m[1][i]);i++;}	}	
	if(m[2] == 1) {insert_marker(m[0],m[1]);}
	
	if(m[2] > 0) {mgr.addMarkers(allmakers,13);mgr.refresh();}
	
}	

function get_and_set(sw_lat,sw_lng,ne_lat,ne_lng){
	$.ajax({
		url: "c4.php",
		type: "POST",
		data: "swlat=" + sw_lat + "&swlng=" + sw_lng + "&nelat=" + ne_lat + "&nelng=" + ne_lng,
		success: function(data){
		if(data != "empty") {
			var data1 = (data).split("*");
			if(data1[2] > 1) {
			var lat = (data1[0]).split("|");var lng = (data1[1]).split("|");
			lat.pop();
			lng.pop();
			} else {
			var lat = data1[0];
			var lng = data1[1];
			}		
			var m = [];
			m.push(lat);
			m.push(lng);
			m.push(data1[2]);

			process_markers(m);
			}
		}		
	});
}
	
	var s_sw_lat = s_sw.lat();
	var s_sw_lng = s_sw.lng();
	var s_ne_lat = s_ne.lat();
	var s_ne_lng = s_ne.lng();
	
	var mgrOptions = {borderPadding: 25};
	var mgr = new MarkerManager(map,mgrOptions);
	
	get_and_set(s_sw_lat,s_sw_lng,s_ne_lat,s_ne_lng);		


GEvent.addListener(map, "dragend", function() {
		var after_bounds = map.getBounds();
		var a_sw = after_bounds.getSouthWest();
		var a_ne = after_bounds.getNorthEast();
		var a_sw_lat = a_sw.lat();
		var a_sw_lng = a_sw.lng();
		var a_ne_lat = a_ne.lat();
		var a_ne_lng = a_ne.lng();
				
		get_and_set(a_sw_lat,a_sw_lng,a_ne_lat,a_ne_lng);
		
	});


К карте привязан listener, то есть, после перетаскивания карты, проверяются вытащенные из базы маркеры с уже теми, что есть на карте и удаляются те, которые уже есть на карте.

Оставшиеся в массиве маркеры, если такие будут, наносятся на карту и добавляются в общий массив маркеров.

Только вот проблема в том, что при перетаскивании иногда происходит вот такое, хотя в базе координат всего на 5 маркеров:

screenshot

У меня почему то проскакивает m[2] в виде единицы, хотя должен быть 0, если на карте уже есть такой маркер.

Помогите пожалуйста разобраться, где я ошибся.

Может в скрипте присутствуют лишние вычисления? Если да, то как их сократить?

x-yuri 05.10.2009 20:42

если четсно, нету желания в таком коде разбираться... приведи пример данных, которые приходят в success

Beck 05.10.2009 21:22



В данном случае на карте было уже два маркера, подгрузились три маркера, из которых должен был добавиться в marger manager один, а добавилось два.

Координаты одного маркера каким то способом проскочили проверку уже существующих маркеров в marker manager(на карте).


На данный момент код такой:

if(all_lat_length > 1) {
	var i = 0;
	var i2 = 0;
	
	if(m[2] > 1) {
		while(i < m[2]){		
		while(i2 < all_lat_length) {
			if(m[0][i] == all_lat[i2]){m[0].splice(i,1);m[1].splice(i,1);console.log(m[2]);m[2]--;console.log(m[2]);}
			i2++;
			}
		i++;
		}
	}
	if(m[2] == 1) {
		var i2 = 0;
		while(i2 < all_lat_length) {
			if(m[0] == all_lat[i2]){m[2] = 0;break;}
			i2++;
			}			
		}
	}		
	
		

	console.log(m[0]);
	console.log(m[1]);
	if(m[2] > 1) {	var i = 0;while(i < m[2]){insert_marker(m[0][i],m[1][i]);i++;}	}	
	if(m[2] == 1) {insert_marker(m[0],m[1]);}

Beck 05.10.2009 21:32

Если в базе новых координат этой области не обнаружено, то firebug должен выдавать такое:



Cтроки:

1) Прилетевший, не отпарсенный ответ
2) Количество непроверенных координат из прилетевшего ответа по отношению к уже существующим на карте
3) Количество непроверенных координат из прилетевшего ответа по отношению к уже существующим на карте
4) 0 совпадений найдено
5) Массив новых координат пуст
6) тоже, что и пятый пункт, просто перед самым добавлением проверяю:

console.log(m[2]);
	if(m[2] > 1) {	var i = 0;while(i < m[2]){insert_marker(m[0][i],m[1][i]);i++;}	}	
	if(m[2] == 1) {insert_marker(m[0],m[1]);}

Beck 05.10.2009 21:44

function insert_marker(lat,lng){
	
	all_lat.push(lat);


Добавление в общий массив координат, которые уже на карте.

x-yuri 05.10.2009 21:47

значит, сервер возвращает некоторое количество пар чисел (координат)? Давай переделаем это на json_encode + eval

Beck 05.10.2009 22:17

Переделал, теперь ответ приходит такой:

{"lat":["56.50097598931345","56.49983904637648"],"lng":["21.01032257080078","20.999422073364258"],"mcount":2}


А дальше как? :) Как заставить эту строку, воспринимать, как объект/массив.

Я так понимаю, что вот таким способом:

var obj= eval("(" + data+ ")");

x-yuri 05.10.2009 22:25

Цитата:

Сообщение от Beck
А дальше как? Как заставить эту строку, воспринимать, как объект/массив.

http://javascript.ru/forum/31724-post10.html - что непонятно?
lat, lng - названия координат?
mcount - количетсво координат? тогда оно лишнее

Beck 05.10.2009 22:49

if(all_lat_length > 1) {
	var i = 0;
	var i2 = 0;	

	if(m['mcount'] > 1) {
		while(i < m['mcount']){		
			while(i2 < all_lat_length) {
				if(m['lat'][i] == all_lat[i2] && m['lng'][i] == all_lng[i2]){m['lat'].splice(i,1);m['lng'].splice(i,1);m['mcount']--;}
				i2++;
				}
		i++;
		}
	}
	if(m['mcount'] == 1) {
		var i2 = 0;
		while(i2 < all_lat_length) {
			if(m['lat'] == all_lat[i2] && m['lng'] == all_lng[i2]){m['mcount'] = 0;}
			i2++;
			}			
		}
	}		
	

	
	if(m['mcount'] > 1) {	var i = 0;while(i < m['mcount']){insert_marker(m['lat'][i],m['lng'][i]);i++;}	}	
	if(m['mcount'] == 1) {	insert_marker(m['lat'],m['lng']);	}
	console.log(mcnt);


console.log(mcnt); должно выводить три, а выводит 4. :(

Beck 05.10.2009 22:51

Цитата:

Сообщение от x-yuri (Сообщение 31785)
http://javascript.ru/forum/31724-post10.html - что непонятно?
lat, lng - названия координат?
mcount - количетсво координат? тогда оно лишнее

lat - latitude
lng - longtitude

mcount - affected_rows(); из последнего запроса

Как проще сделать сравнение списка текущих координат и списка новых?

Beck 05.10.2009 23:39

if(all_lat_length > 1) {	
	newlat = array_diff(m['lat'],all_lat);newlng = array_diff(m['lng'],all_lng);
	console.log(newlat);console.log(newlng);
	for(i = 1;i < newlat.length;i++){insert_marker(newlat[i],newlng[i]);} 
	}	
	else {
	if(m['mcount'] > 1) {	for(i = 0;i < m['lat'].length;i++)	{insert_marker(m['lat'][i],m['lat'][i]);}	} 
	else {insert_marker(m['lat'],m['lng']);}
	}
	console.log(mcnt);


Нашел функцию у вас на сайте:
function array_diff (array) {    // Computes the difference of arrays
    // 
    // +   original by: Kevin van Zonneveld ([url]http://kevin.vanzonneveld.net[/url])
 
    var arr_dif = [], i = 1, argc = arguments.length, argv = arguments, key, key_c, found=false;
 
    // loop through 1st array
    for ( key in array ){
        // loop over other arrays
        for (i = 1; i< argc; i++){
            // find in the compare array
            found = false;
            for (key_c in argv[i]) {
                if (argv[i][key_c] == array[key]) {
                    found = true;
                    break;
                }
            }
 
            if(!found){
                arr_dif[key] = array[key];
            }
        }
    }
 
    return arr_dif;
}

Прогнал через нее оба массива, вроде всё работает, но как доработать, чтобы сверять и широту и долготу одновременно.

И еще, почему-то в newlat нулевой слот стоит undefined, как и в newlng.
Почему так?

Beck 06.10.2009 15:36

Эх, никто не хочет разбираться в коде. :D

В общем кое как сделал, вроде работает всё, только вот почему undefined, после прогона через array_diff, так и не разобрался.

Теперь бы еще сделать сравнения видимой зоны и той, что будет, после dragend.

А то на каждый dragend евент делать запрос к базе, то так и сервер загнется. :D

Kolyaj 06.10.2009 15:47

Цитата:

Сообщение от Beck
Эх, никто не хочет разбираться в коде.

Вы бы отформатировали его хотя бы. Вы думаете это реально прочесть?
if(m['lat'][i] == all_lat[i2] && m['lng'][i] == all_lng[i2]){m['lat'].splice(i,1);m['lng'].splice(i,1);m['mcount']--;}

Beck 06.10.2009 16:03

Сейчас выложу кусок кода, где сравнения производятся.

x-yuri 06.10.2009 16:04

Цитата:

Сообщение от Kolyaj
Вы бы отформатировали его хотя бы

хотя бы вот этим beautifier, если сам не хочешь читабельно писать

x-yuri 06.10.2009 16:28

а вообще, я бы принимал массив вида
[{"lat":"56.50097598931345","lng":"21.01032257080078"},{"lat":"56.49983904637648","lng":"20.999422073364258"}]

и заменил вот этот код на
for( var i=0; i<markers.length; i++ )
    for( var j=0; j<allMarkers.length; j++ )
        if( markers[i].lat == allMarkers[j].lat &&   markers[i].lng == allMarkers[j].lng ) {
            markers.splice( i, 1 );
            i--;
            break;
        }
for( var i=0; i<markers.length; i++ )
    insertMarker( markers[i] );
allMarkers = allMarkers.concat( markers );

Beck 06.10.2009 16:43

// all_lat это общий массив широт(latitude), которые уже на карте

//m[] это данные из ответа сервера	
	
console.log(all_lat); = ["56.50097598931345", "56.49983904637648"]
console.log(m['lat']); = ["56.50097598931345", "56.53734016907318", "56.49983904637648"]

	newlat = array_diff(m['lat'],all_lat);
	newlng = array_diff(m['lng'],all_lng);

        // вот это в firebug выдает, при появлении на карте трех маркеров, из которых 1 новый
        console.log(newlat); = [undefined, "56.53734016907318"]

// newlat это массив широт для новых маркеров на карте

Beck 06.10.2009 16:47

Цитата:

Сообщение от x-yuri (Сообщение 31905)
а вообще, я бы принимал массив вида
[{"lat":"56.50097598931345","lng":"21.01032257080078"},{"lat":"56.49983904637648","lng":"20.999422073364258"}]

и заменил вот этот код на
for( var i=0; i<markers.length; i++ )
    for( var j=0; j<allMarkers.length; j++ )
        if( markers[i].lat == allMarkers[j].lat &&   markers[i].lng == allMarkers[j].lng ) {
            markers.splice( i, 1 );
            i--;
            break;
        }
for( var i=0; i<markers.length; i++ )
    insertMarker( markers[i] );
allMarkers = allMarkers.concat( markers );

Спасибо! Вроде все понятно, только вот i--; не совсем уловил зачем?
Можете объяснить?

x-yuri 06.10.2009 16:48

Цитата:

Сообщение от Beck
Вроде все понятно, только вот i--; не совсем уловил зачем?

а ты попробуй поразбираться/поотлаживать... Это полезно. В общем console.log в помощь ;)

Beck 06.10.2009 16:49

Цитата:

Сообщение от x-yuri (Сообщение 31915)
а ты попробуй поразбираться/поотлаживать... Это полезно. В общем console.log в помощь ;)

Сейчас же примусь! :)

Теперь хочу реализовать проверку зон, из которых маркеры уже вытаскивались из базы.

Только вот как бы это реализовать, чтобы не было "слепых зон","пустых зон".

e1f 06.10.2009 17:01

Цитата:

Сообщение от x-yuri (Сообщение 31905)
а вообще, я бы принимал массив вида
[{"lat":"56.50097598931345","lng":"21.01032257080078"},{"lat":"56.49983904637648","lng":"20.999422073364258"}]

x-yuri,
а я бы (если записей станет больше)
{"head":["lat", "lng"], "rows":[["56.50097598931345", "21.01032257080078"],["56.49983904637648", "20.999422073364258"]]}

Компактней, можно читабельные имена полей задавать, без ущерба для траффика.

x-yuri 06.10.2009 17:05

Цитата:

Сообщение от Beck
Только вот как бы это реализовать, чтобы не было "слепых зон","пустых зон".

а откуда они появяться?

e1f, пожалуй +1 :)


Часовой пояс GMT +3, время: 22:25.