[js, ajax, json] Помогите скриптик наваять...
Ща пример найду.
$.ajax({
url: 'http://server.com/map.php?pointID=13,
dataType: 'json',
timeout: 20000,
success: function(jsondata) {
data=JSON.parse(jsondata);
...
},
error: function() {
}
});
На php скрипт сам напишешь?
На php скрипт сам напишешь?врядли. я собственно надеялся что просто соберу из кусочков и примеров на яндексе то что мне нужно, но наткнулся на своё незнание ни яваскрипта, ни пхп.
Да, не видать тебе 400 к и каена.
$.ajax({
url: 'http://server.com/13.json',
dataType: 'json',
timeout: 20000,
success: function(jsondata) {
data=JSON.parse(jsondata);
... //дальше тут идет работа с этим массивом data
},
error: function() {
}
});
Поскольку dataType: 'json' уже указан, то JSON.parse не нужен.
Поверь, бывают исключения.
Я верю в исключения, но не понимаю как работает JSON.parse если передать ему объект.
код выдаёт
error1
error2
test.json лежит где надо, если дать неправильный путь - ругается на 404. браузером файл скачивается.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Быстрый старт. </title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<script src="//api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU" type="text/javascript"></script>
<script src="//code.jquery.com/jquery-1.10.2.js" type="text/javascript"></script>
<script type="text/javascript">
// Дождёмся загрузки API и готовности DOM.
ymaps.ready(init);
function init() {
$.ajax({
url: '/test.json',
dataType: 'json',
timeout: 20000,
success: function(jsondata) {
//дальше тут идет работа с этим массивом data
console.log('success1');
},
error: function() {
console.log('error1');
}
});
$.getJSON( "/test.json", function() {
console.log( "success2" );
})
.fail(function() {
console.log( "error2" );
})
}
</script>
</head>
<body>
</body>
</html>
http://som.server.com/test.json
Или у тебя апач не поднят и локально пытаешься работать?
Попробуй указать полный путь (url), типа, Или у тебя апач не поднят и локально пытаешься работать?
полный путь выдаёт такой же результат.
Если в файле ровно то, что ты написал, то там не хватает запятых между pointx и pointy. И лишняя запятая в 21 строчке
спасибо большое всем.
И лишняя запятая в 21 строчкеа точно ли ?
вроде она синтаксисом допустима
расскажи это IE
В JSON нельзя.
в ИЕ работает через раз. в хроме всё норм.
при открытии страницы - выдаёт ошибку. при f5 - показывает.
http://vvvk.ru/test.html
при удачном открытии должно показывать маршрут.
при неудачном - грузит карту, в консоль вылезает такая ошибка:
SCRIPT5007: Не удалось получить свойство "length" ссылки, значение которой не определено или является NULL
File: combine.xml, Line: 1, Column: 385016
или
test.html, строка 28 символ 2
такое ощущение что не успевает что-то загрузиться из src, в 28 строке вызывается метод яндекс карт, хотя ранее в коде уже было обращение к яндекскартам.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Карта</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<script src="//api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU" type="text/javascript"></script>
<script src="//code.jquery.com/jquery-1.10.2.js" type="text/javascript"></script>
<script type="text/javascript">
ymaps.ready(init);
var ar;
$.getJSON( "/test.json", function(data) {
ar = data.points;
})
.fail(function() {
console.log( "error" );
})
function init() {
var myMap = new ymaps.Map("map", {
center: [51.674148,39.293907],
zoom: 8
});
myMap.behaviors.enable('scrollZoom');
ymaps.route(
ar,
{
mapStateAutoApply: true
}).then(function (route) {
myMap.geoObjects.add(route);
var points = route.getWayPoints(),
lastPoint = points.getLength() - 1;
points.options.set('preset', 'twirl#redStretchyIcon');
points.get(0).properties.set('iconContent', 'Точка отправления');
points.get(lastPoint).properties.set('iconContent', 'Точка прибытия');
}, function (error) {
alert('Возникла ошибка: ' + error.message);
});
}
</script>
</head>
<body>
<div id="map" style="width: 1000px; height: 800px"></div>
</body>
</html>
Init срабатывает до подгрузки json.
При обновлении через F5 (без Ctrl) json (т.к. статический файл и не менялся) уже лежит в кэше.
как сделать, чтобы инит вызывался после всех приготовлений?
ymaps.ready(init);
function init() {
var ar;
var myMap = new ymaps.Map("map", {
center: [51.674148,39.293907],
zoom: 8
});
$.getJSON( "/test.json", function(data) {
ar = data.points;
ymaps.route(
ar,
{
mapStateAutoApply: true
}).then(function (route) {
myMap.geoObjects.add(route);
var points = route.getWayPoints(),
lastPoint = points.getLength() - 1;
points.options.set('preset', 'twirl#redStretchyIcon');
points.get(0).properties.set('iconContent', 'Точка отправления');
points.get(lastPoint).properties.set('iconContent', 'Точка прибытия');
}, function (error) {
alert('Возникла ошибка: ' + error.message);
});
})
.fail(function() {
console.log( "error" );
})
myMap.behaviors.enable('scrollZoom');
}
Это на скорую руку.
var ar;
$.getJSON( "/test.json", function(data) {
ar = data.points;
ymaps.ready(init);
})
.fail(function() {
console.log( "error" );
})
а оно точно будет работать, если яндекс карты инициализируются до прихода json?
Делать запрос на JSON внутри Init, прокладывать маршрут после получения JSON.я сначала так и сделал. тогда всегда выдаёт эту ошибку, даже по f5
если внести инит внутрь getjson - остаётся также, при загрузке ошибка, по ф5 - работает. (на одном из компов работает и без ф5, но видимо это просто вопрос быстродействия самого браузера или типа того)
не знаю, может что-то просто оставалось в кеше и грузился старый вариант, но этот способ вроде бы помог. спасибо.
Попробуй.
Ну, при таком способе init вызывается только при условии получения успешного ajax ответа и заполнения переменной ar.
спасибо большое.
здесь я имею на входе массив точек, далее нахожу маршруты от первой точки до каждой из остальных и выбираю кратчайший, записываю в массив и уже от этой точки повторяю действие до оставшихся. типа ищу "оптимальный" маршурт по расстоянию.
получается куча запросов на построение маршрутов к яндексу. как заставить скрипт ждать каждого ответа от сервера?
при отладке строка 57 выдаёт 10 раз "del 0", а потом уже приходят все ответы от сервера.
в инете видел что-то про вызов сторонней функции, но не могу придумать как это тут вкрячить. подскажете?
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Карта</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<script src="//api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU" type="text/javascript"></script>
<script src="//code.jquery.com/jquery-1.10.2.js" type="text/javascript"></script>
<script src="//yandex.st/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
ymaps.ready(init);
function init()
{
var ar;
var myMap = new ymaps.Map("map",
{
center: [51.674148,39.293907],
zoom: 8
});
myMap.behaviors.enable('scrollZoom');
var res = [];
var temp = [];
$.getJSON( "/test.json", function(data)
{
ar = data.points;
var curPoint = ar[0];
while (ar.length > 0)
{
l = 999999;
var curID = 0;
for (var i = 0; i < ar.length; i++)
{
test = [curPoint,ar[i]];
ymaps.route(
test,
{})
.then(function (route)
{
if (route.getLength()<=l)
{
l=route.getLength();
curPoint = ar[i];
curID = i;
};
}, function (error)
{
alert('Возникла ошибка: ' + error.message);
});
};
res.push(curPoint);
ar.splice(curID,1);
console.log('del ' + curID);
}
//console.log(res);
/* ymaps.route(
res,
{mapStateAutoApply: true})
.then(function (route)
{
myMap.geoObjects.add(route);
myMap.setBounds(myMap.geoObjects.getBounds());
var points = route.getWayPoints(),
lastPoint = points.getLength() - 1;
points.options.set('preset', 'twirl#redStretchyIcon');
points.get(0).properties.set('iconContent', 'Точка отправления');
points.get(lastPoint).properties.set('iconContent', 'Точка прибытия');
}, function (error)
{
alert('Возникла ошибка: ' + error.message);
});
*/
});
}
</script>
</head>
<body>
<div id="map" style="width: 1000px; height: 800px"></div>
</body>
</html>
for (var i = 0; i < ar.length; i++)Сдается мне, что тут надо начинать от 1, ибо расстояние между точкой и ей самой равно 0.
можно сэкономить одну итерацию, да.
search: jquery when all
наткнулся на проблему с асинхронными запросами. в результате цикл отрабатывает вхолостую, не делая то, чего мне нужно.Да нет тут вроде никакой проблемы. По крайней мере она не в асинхронном запросе. Цикл отрабатывается не в холостую.
Чтобы в этом убедиться, достаточно в js добавить еще логи.
ymaps.ready(init);
function init()
{
var ar;
var myMap = new ymaps.Map("map",
{
center: [51.674148,39.293907],
zoom: 8
});
myMap.behaviors.enable('scrollZoom');
var res = [];
var temp = [];
$.getJSON( "/test.json", function(data)
{
ar = data.points;
console.log('got ' + ar.length + ' points');
var curPoint = ar[0];
while (ar.length > 0)
{
l = 999999;
var curID = 0;
console.log('processing ' + (ar.length - 1) + ' points');
for (var i = 1; i < ar.length; i++)
{
test = [curPoint,ar[i]];
ymaps.route(
test,
{})
.then(function (route)
{
if (route.getLength()<=l)
{
console.log('changing ' + l + ' to ' + route.getLength());
l=route.getLength();
curPoint = ar[i];
curID = i;
}
else
{
console.log('Not changing ' + l + ' to ' + route.getLength());
};
}, function (error)
{
alert('Возникла ошибка: ' + error.message);
});
};
res.push(curPoint);
ar.splice(curID,1);
console.log('del ' + curID);
}
});
}
Строки 25, 36, 40-42.
Позже приведу код того, что ты хочешь (если это не сделают до меня или сам не успеешь разобраться).
А пока ключевые слова: рекурсивная функция.
Чтобы в этом убедиться, достаточно в js добавить еще логи.я добавлял так. проверял, что ответы приходят уже после того, как выполняется весь цикл while. вот:
про рекурсию я подумаю, спасибо.
ymaps.ready(init);
var promise;
// Автопереносилка. Функция перемещает элемент из одного массива в другой
var moveArrayElement = function(sourceArray, index, destArray)
{
destArray.push(sourceArray[index]);
sourceArray.splice(index, 1);
console.log('del ' + index);
};
// Вместо тысячи слов: http://s.pikabu.ru/post_img/2013/05/08/9/1368018276_177184489.jpeg
var shortPath = function(
pointArray, // Массив исходных точек
destArray, // Целевой массив упорядоченных точек
index, // Индекс точки с кратчайшим расстоянием
offset, // Отступ от подходящего индекса
lenToCompare // Сравниваемая длина
)
{
if (destArray.length == 0) // Если в целевом массиве еще нет точек, заносим первую из исходного
{
moveArrayElement(pointArray, 0, destArray);
shortPath(pointArray, destArray); // Рекурсивный вызов
}
else if (pointArray.length > 1) // Если исходный массив имеет больше одного элемента
{
var i, o;
if (typeof(index) === 'undefined') // Если индекс отсутствует
{
i = 0;
o = 0;
}
else
{
i = index;
o = offset;
};
if (i + o == pointArray.length) // Если индекс в сумме с отступом равен длине массива (перевалил), то следующий индекс найден
{
moveArrayElement(pointArray, i, destArray);
shortPath(pointArray, destArray); // Рекурсивный вызов с обновленными массивами
}
else
{
path = [destArray[destArray.length - 1], pointArray[i + o]];
ymaps.route(path, {})
.then(function (route)
{
console.log('index: ' + i + ', offset: ' + o + ', length: ' + route.getLength());
if (o == 0) // Если отсуп нулевой, то нет длины для сравнения
{
shortPath(pointArray, destArray, i, 1, route.getLength()); // Рекурсивный вызов c указанием сравниваемой длины
}
else if (lenToCompare >= route.getLength()) // Если длина для сравнения больше текущей, переопределяем индекс и продолжаем от него
{
shortPath(pointArray, destArray, i + o, 1, route.getLength());
}
else
{
shortPath(pointArray, destArray, i, o + 1, lenToCompare);
};
}, function (error)
{
alert('Возникла ошибка: ' + error.message);
});
}
}
else if (pointArray.length == 1) // Если в исходном массиве осталась только одна точка, переносим ее.
{
moveArrayElement(pointArray, 0, destArray);
promise.resolve(destArray);
};
};
function init()
{
var ar;
promise = new ymaps.util.Promise();
promise.then(
function(fin){
console.log('final array is: ' + fin.length);
}
);
var myMap = new ymaps.Map("map",
{
center: [51.674148,39.293907],
zoom: 8
});
myMap.behaviors.enable('scrollZoom');
var res = [];
$.getJSON( "/test.json", function(data)
{
ar = data.points;
console.log('got ' + ar.length + ' points');
shortPath(ar, res);
});
}
но всё же...
console.log('got ' + ar.length + ' points');
shortPath(ar, res);
console.log('res ' + res.length + ' points');
сходу добавить туда deferred() объект у меня не получилось.
за советы и помощь спасибо. думаю...
Что нового по сравнению с предыдущим:
строки 3, 73, 80-85;
Содержание 83 строки — это то, что будет выполняться после всех манипуляций.
Честно говоря, такая штука, как обещание, провоцирует пересмотреть и упростить код. Но сейчас этим заниматься нет времени.
спасибо ещё раз. работает.
Оставить комментарий
nas1234
допустим есть такой кодв некоторой внешней программе я создам json файлик с этими пойнтами и положу его на сервер, где выполняется этот скрипт.
так будет выглядеть?
13.json
как мне в коде обратиться к этому файлику, чтобы получить из него массив ar?
желательно бы чтобы я мог в адресной строке передать номер файла 13. типа site.ru/map.php?pointID=13 и тогда парится файл 13.json