Javascript каждый цикл над JSON, получая только первый элемент? - PullRequest
2 голосов
/ 12 января 2011

Я использую Jquery Mobile, так что игнорируйте некоторые из приведенных ниже css, это не связано с основной проблемой.

У меня проблема с зацикливанием "мест" в моем объекте JSON-пакета / javascript. Я получаю ответ с несколькими «Местами», но не могу понять, как их перебирать. Моя переменная 'i' в каждом цикле работает правильно для первого элемента и отображает соответствующее имя и изображение.

Вот мой серверный вид Django (довольно простой, если вы не знакомы с Python):

def tonight_mobile(request):

    callback = request.GET.get('callback', '')

    def with_rank(rank, place):
        return (rank > 0)

    place_data = dict(
        Places = [make_mobile_place_dict(request, p) for p in Place.objects.all()]
    )

    xml_bytes = json.dumps(place_data)
    return HttpResponse(xml_bytes, content_type='application/json; charset=utf-8')

Мой сервер подтверждает запрос и возвращает следующее:

"GET /api/0.1/tonight-mobile.json&callback=jsonp1293142434434 HTTP/1.1" 200 167

Вот мой ответ:

callback({"Places": [{"url": "http://localhost:8000/api/0.1/places/3.plist", 
"image_url": "http://localhost:8000/static/place_logos/Bengals_1.png", 
"name": "Bob's Place", "events": 2}, 
{"url": "http://localhost:8000/api/0.1/places/2.plist", 
"image_url": "http://localhost:8000/static/place_logos/Makonde_Mask.gif", 
"name": "My Bar", "events": 0}, 
{"url": "http://localhost:8000/api/0.1/places/1.plist", 
"image_url": "http://localhost:8000/static/place_logos/Quintons_1.png", 
"name": "Quinton's", "events": 1}]})

------------

Мой getJSON и метод обратного вызова превратились в это:

<script>
function loadJSON(){
    $.getJSON("http://localhost:8000/api/0.1/tonight-mobile.json&callback=?", callback(data));
}
function callback(data){
    $("#tonight-list").each(data.Places, function(i) {
        $(this).append("<li role='option' tabindex='" + data.Places[i] + "' class='ui-li-has-thumb ui-li ui-btn ui-btn-icon-right ui-corner-top ui-corner-bottom ui-controlgroup-last ui-btn-down-c ui-btn-up-c' data-theme='c'><div class='ui-btn-inner ui-corner-top ui-corner-bottom ui-controlgroup-last'><span class='ui-icon ui-icon-arrow-r'></span><div class='ui-btn-text'><img src=" + data.Places[i].image_url + " alt=" + data.Places[i].name + " class='ui-li-thumb ui-corner-tl ui-corner-bl'/><h1 class='list-title ui-li-heading' id='list-title'><a href='detail.html?id=slide' data-transition='slide' class='ui-link-inherit'>" + data.Places[i].name + "</a></h1><span class='ui-li-count ui-btn-up-c ui-btn-corner-all'>" + data.Places[i].events + " events</span></div></div></li>");
    });

}
</script>

Я не понимаю, как каждая функция выполняет итерации по объектам JSON (которые становятся) Javascript? Я почти уверен, что каждый из них - моя проблема здесь, так как я получаю только ПЕРВЫЙ элемент списка «Места». Может кто-нибудь помочь мне с тем, как структурировать цикл?

Ответы [ 2 ]

2 голосов
/ 12 января 2011

Вы используете getJSON и each неправильный путь:

function loadJSON(){
    $.getJSON("http://localhost:8000/api/0.1/tonight-mobile.json&callback=?", callback);
}
function callback(data){
    var target = $("#tonight-list");
    $.each(data.Places, function(i) {
        target.append("...");
    });
}

Вы должны передать ссылку функции обратного вызова, чтобы getJSON, а не вызывать функцию.

Если вы делаете $("#tonight-list").each(), то вы перебираете элементы, выбранные селектором. Эта функция в любом случае принимает только один аргумент (обратный вызов). См. Документацию .

Вы хотите $.each(), который принимает массив в качестве первого и обратный вызов в качестве второго аргумента.

2 голосов
/ 12 января 2011

each() не работает таким образом.Он принимает набор элементов на странице и перебирает их, вызывая функцию для каждого из них.В этом случае вы перебираете $("#tonight-list"), в котором будет только один элемент (идентификаторы должны однозначно идентифицировать один элемент в документе).

То, что вы хотите сделать, - это циклповерх data (не элемента #tonight-list) и добавьте данные в этот элемент, верно?В этом случае вы хотите, чтобы обычный JavaScript выполнял цикл, что-то вроде этого:

var list = $("#tonight-list");
for (var i=0, place; place=data.Places[i]; ++i) {
    list.append("<li role='option' tabindex='" + i + "'>" + place.name + "</li> ...etc);
}

Обратите внимание, что я понятия не имею, загружаете ли вы надежные данные, которые должны содержать HTML, ненадежный простой текст и т. Д.. Возможно, вам придется кодировать данные перед вставкой или (лучше) вставить их структурно, а не объединять строки, в зависимости от вашего варианта использования.

...