Jquery добавляет атрибут заголовка с данными из вызова JSON

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

Это то, что у меня есть до сих пор

$(".watch_view img").each(function() {
$.ajax({
    url: 'http://gdata.youtube.com/feeds/api/videos/T2aMBeeM4yw?v=2&alt=jsonc',
    dataType: 'json',
    success: function(json) {   
    song_title = json.data.title;// song title is retrieved without issue                           
    }   
    });

   alert(song_title); //this to be removed
   //the title attr below is only added when the above alert is in place    
   $(this).attr('title', song_title);
   $(this).attr('alt', "This works everytime"); 
   });

Теперь вышеприведенное работает, но только когда я «останавливаю» процесс, добавляя нежелательное предупреждение — я могу только догадываться, что код выполняется до того, как он извлекает данные из вызова JSON (?), И предупреждение позволяет ему наверстать упущенное. .

Я предполагаю, что мне нужна другая функция, которая выполняется после вызова JSON или для того, чтобы код перешел в функцию «успех», но я не уверен, как удержать элемент «этот», если это так.

Помощь и совет очень ценятся.

Спасибо

Крис


person Chris    schedule 16.10.2012    source источник
comment
УСПЕХ и есть эта функция!!! Вы пытались использовать $(this) внутри success. AFAIR это не должно быть проблемой   -  person TJ-    schedule 16.10.2012
comment
Он не выдает ошибку внутри успеха (что бы это ни было), но не добавляет атрибут заголовка. Оповещение в этом месте показывает, что получены правильные данные.   -  person Chris    schedule 16.10.2012


Ответы (4)


Имейте в виду, что AJAX означает асинхронный JavaScript. Это означает, что браузер не будет зависать, пока идет связь с сервером.

Когда вы вызываете функцию $.ajax(...), скрипт продолжает работу после нее, не дожидаясь ответа (вы можете настроить его на ожидание, но тогда это будет синхронный вызов).

Когда сервер успешно завершит работу, вы должны отреагировать на это событие, поэтому ваш код обработки ответа должен находиться в теле функции success:

$(".watch_view img").each(function (index,element) {
    $.ajax({
        url: 'http://gdata.youtube.com/feeds/api/videos/T2aMBeeM4yw?v=2&alt=jsonc',
        dataType: 'json',
        success: function (json) {
            song_title = json.data.title; // song title is retrieved without issue                           
            $(element).attr('title', song_title);
            $(element).attr('alt', "This works everytime");
        }
    });

});

В вашем старом коде оповещение было получено до того, как сервер вернулся. Когда вы установили точку останова, это сработало, потому что у сервера было достаточно времени, чтобы вернуть ответ, пока вы занимались обработкой человеческого времени :)

Обновить

Кроме того, вы должны знать, что this внутри обратного вызова success относится к возвращаемым данным, переопределяя ожидаемый this для each (который будет итерируемым элементом). Вы должны фактически объявить параметры для вызова each, чтобы вы могли вернуться к ним внутри успешного вызова.

person Adriano Carneiro    schedule 16.10.2012
comment
Перемещение его внутри успеха ничего не возвращает в атрибутах (даже для фиксированного атрибута alt) - person Chris; 16.10.2012
comment
Не могли бы Вы уточнить? Вы только что заявили в своем вопросе, что song_title = json.data.title; работает нормально. Что конкретно сейчас не работает? - person Adriano Carneiro; 16.10.2012
comment
извините - если у меня есть предупреждение (название песни), оно показывает правильные данные, однако атрибуты остаются пустыми. - person Chris; 16.10.2012
comment
Извините, ребята, но все еще не работает - я вставил его в JSfiddle. Может, кто-нибудь проверит мою психику? jsfiddle.net/VT6vP/3 - person Chris; 16.10.2012
comment
Адриан - большое спасибо, ваше обновление решило проблему. Пропустил это, пока возился с jsfiddle - еще раз спасибо - person Chris; 16.10.2012

$(".watch_view img").each(function() {
$.ajax({
    url: 'http://gdata.youtube.com/feeds/api/videos/T2aMBeeM4yw?v=2&alt=jsonc',
    dataType: 'json',
    success: function(json) {   
        song_title = json.data.title;// song title is retrieved without issue 

       $(this).attr('title', song_title);
       $(this).attr('alt', "This works everytime");                           
    }   
    });
});

Вам нужно правильно использовать обратный вызов успеха. Надеюсь, это поможет.

Обратные вызовы используются для асинхронного javascript, иначе вы получите условия гонки (то, что вы видели).

person Michael Rice    schedule 16.10.2012

Вызов ajax является асинхронным, что означает, что когда вы устанавливаете заголовок, сервер все еще обрабатывает ваш запрос. Когда вы ставите нежелательное оповещение, вы на некоторое время останавливаете клиент, а сервер отвечает на запрос, поэтому он работает.

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

person Thiago    schedule 16.10.2012

Вы можете попробовать этот

var _song_title = ''
$(".watch_view img").each(function() {    
$.ajax({
    url: 'http://gdata.youtube.com/feeds/api/videos/T2aMBeeM4yw?v=2&alt=jsonc',
    dataType: 'json',
    success: function(json) {   
    _song_title = json.data.title;// song title is retrieved without issue                           
    }   
    }).done(function(){
        alert(_song_title); //this to be removed
   //the title attr below is only added when the above alert is in place    
   $(this).attr('title', _song_title);
   $(this).attr('alt', "This works everytime");
    });
person Vikram    schedule 16.10.2012