Проблема с созданием списка HTML (li) с функцией обратного вызова - PullRequest
1 голос
/ 22 марта 2011

Я сталкиваюсь с этой досадной проблемой со связыванием правильного значения с правой строкой в ​​моем HTML-списке, который я отображаю. Думаю, объяснение моего кода было бы лучшим способом объяснить, поэтому здесь я иду.

У меня есть строка json, которая возвращает данные о нескольких игроках из базы данных.У игроков может быть несколько записей.

Моя строка имеет вид

jsonVar = {"someStr":[{"Fbid":"xxxxxxxxx","score":"xxxxxx","game":"x","date":"1300689902"}, .... }]

Теперь я хочу отобразить данные в виде списка в HTML для всех столбцов.

createList = function()
{
arrayLength = jsonVar.someStr.length;
for(i=0;i<arrayLength;i++)
{
    listName = document.id('name');
    listScore = document.id('score');
    listGameMode = document.id('gamemode');
    listTime = document.id('time');                             
    listfbID= document.id('fbID');

    fbId = jsonVar.someStr[i].Fbid;

    FB.api('/'+fbId+'/', function(response) 
    {   
         new Element('li',{text: response.first_name +" "+response.middle_name+" "+response.last_name }).inject(listName, 'bottom');        
    });
    new Element('li',{text:jsonVar.someStr[i].Fbid}).inject(listfbID, 'bottom');
    new Element('li',{text: jsonVar.someStr[i].score}).inject(listScore, 'bottom');
    new Element('li',{text:jsonVar.someStr[i].gamemode}).inject(listGameMode, 'bottom');
    new Element('li',{text: jsonVar.someStr[i].date}).inject(listTime, 'bottom');

    }
}   

Проблема была бы в том, что имя неправильно возвращалось с остальными записями в списке, это, я полагаю, связано с некоторой задержкой с возвратом имени из fb.

Ответы [ 5 ]

1 голос
/ 22 марта 2011

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

FB.api('/'+fbId+'/', ( function() {
    var current_i = i;
    return function(response) 
       {   
         new Element('li',{text: response.first_name +" "+response.middle_name+" "+response.last_name }).inject(listName, 'bottom');        
         new Element('li',{text:jsonVar.someStr[current_i].Fbid}).inject(listfbID, 'bottom');
         new Element('li',{text: jsonVar.someStr[current_i].score}).inject(listScore, 'bottom');
         new Element('li',{text:jsonVar.someStr[current_i].gamemode}).inject(listGameMode, 'bottom');
         new Element('li',{text: jsonVar.someStr[current_i].date}).inject(listTime, 'bottom');
       };
    })() );

общий пример с обратными вызовами замыкания и ajax на http://jsfiddle.net/gaby/zZ74b/

1 голос
/ 22 марта 2011

Вы имеете в виду время UNIX? Может быть, вы можете использовать что-то вроде этого?

var newDate = new Date();
newDate.setTime(unix*1000);
dateString = newDate.toUTCString();

Где Unix - твое время.

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

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

createList = function() {
arrayLength = jsonVar.someStr.length;
for (i = 0; i < arrayLength; i++) {
    listName = document.id('name');
    listScore = document.id('score');
    listGameMode = document.id('gamemode');
    listTime = document.id('time');
    listfbID = document.id('fbID');

    fbId = jsonVar.someStr[i].Fbid;

    new Element('li', {
        text: jsonVar.someStr[i].Fbid
    }).inject(listfbID, 'bottom');
    new Element('li', {
        text: jsonVar.someStr[i].score
    }).inject(listScore, 'bottom');
    new Element('li', {
        text: jsonVar.someStr[i].gamemode
    }).inject(listGameMode, 'bottom');
    new Element('li', {
        text: jsonVar.someStr[i].date
    }).inject(listTime, 'bottom');
    new Element('li', {
        text: "loading"
    }).inject(listName, 'bottom');

    FB.api('/' + fbId + '/', function(response) {
        var connect;
        parent_id = $('fbID');
        child_id = parent_id.getElementsByTagName('li');

        for (j = 0; j < child_id.length; j++) {
            if (response.id == child_id[j].innerHTML) {
                parent_name = $('name');
                child_name = parent_name.getElementsByTagName('li');
                child_name[j].innerHTML = response.first_name + " " + response.middle_name + " " + response.last_name;
            }
        }
    });

}

}

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

Я думаю, что проблема возникает из-за того, что FB.api () делает асинхронный запрос XMLHttpRequest в отношении Facebook.Предоставленная вами функция обратного вызова будет выполнена через некоторое время, в то время как ваш цикл for продолжает выполняться.

Вы не можете заставить FB.api () работать синхронно, и вы не должны этого делать, потому чтоэто очень сильно замедлит процесс создания списка и приведет к большому количеству запросов к Facebook.

ИМХО приемлемым решением будет сохранение этих полей имени, отчества и фамилии в собственной базе данных и передачаэто с точки зрения PHP.

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

Попробуйте это ..

FB.api('/'+fbId+'/', function(response)
{       
    new Element('li',{text: response.first_name +" "+response.middle_name+" "+response.last_name }).inject(listName, 'bottom');
    new Element('li',{text:jsonVar.someStr[j].Fbid}).inject(listfbID, 'bottom');     
    new Element('li',{text: jsonVar.someStr[j].score}).inject(listScore, 'bottom');     
    new Element('li',{text:jsonVar.someStr[j].gamemode}).inject(listGameMode, 'bottom');     
    new Element('li',{text: jsonVar.someStr[j].date}).inject(listTime, 'bottom');   
    j++;          
});

Но только если вы уверены, что fb API вернет данные в том порядке, в котором вы их вызвали.

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