2016-08-17 54 views
2

我做了一个个人项目,我可以在搜索栏中输入电影标题并获取有关它们的信息。数据在使用omdb的api的json中。下面是代码的主要部分:在动态创建的div中创建分区

//film[] is an array of strings contains movie titles 

//this array works perfectly giving me 0 through lenght-1 elements 
for(var i= 0; i< film.length; i++) 
    console.log(i+" : "+film[i]); 
console.log("Film you entered is "+ film); 

//#load is section element that is use to display "loading" while the data is recieved 
$('#load').html("<h2>LOadiNG.....................</h2>"); 

//looping for each movie 
for(var j= 0; j< film.length; j++){ 
    $.getJSON("http://www.omdbapi.com/?t="+film[j]+"&y=&plot=short&r=json", function(json) { 

     //does not work if I give 3 titles, shows "processing 3 : undefined" all the time 
     console.log("processing "+j+" : "+film[j]); 

     /* 
     *#info is section element where the data is displayed 
     *".for-info" styles each div child inside section so that each movie has a visible seperation 
     *(this is what I want) 
     */ 
     $("#info").append("<div id="+j+" class='for-info'></div>"); 
     $('#load').empty(); 

     //append each key-value in its particular div 
     for(val in json) 
      $("#"+j).append('<p>'+val+' --> '+json[val]+'</p>'); 
     $("#"+j).append("<p><br/></p>"); 
}); 

所以我的问题是如何创建使用DIV使得每个电影数据是1个特别部分师?另外我注意到,有时候索引较高的电影会在较低索引之前被检索出来。当我使用循环来控制它时,这怎么可能?

+2

可以,因为它使用异步方法,有时意为检索结果可能需要更长的等待时间大约一个电影具有更高的索引检索数据和结果可能会略有不同的顺序(被退回,因为代码继续,而不是停止并等待返回的值,然后继续)。为了避免这种情况,可能需要将数据抓取到本地数组,并且一旦完成迭代该数组。 –

+2

'getJSON()'是_asynchronous_,所以您可能会以不同于发送请求的顺序获得您的响应。 – dave

回答

1

作为的WhiteHat说得好,$ .getJSON是异步的,不能保证在另一个之前将完成。你也可以在$ .getJSON完成之前看到'j'的值发生了变化。

如果要确保getJSON同步运行,可以使用promises

在jQuery 1.5中,Ajax方法返回promise。返回值包含getJSON完成时运行的.done(),.always()和.fail()方法。

function processFilms (film, i) { 
    if(!i) i = 0; 
    if (film && i >= 0 && i < film.length){ 
     $.getJSON("http://www.omdbapi.com/?t="+film[i]+"&y=&plot=short&r=json") 
     .done(
     function (json) { 
      console.log("processing "+i+" : "+film[i]); 
      $("#info").append("<div id="+i+" class='for-info'></div>"); 
      for(val in json) 
       $("#"+i).append('<p>'+val+' --> '+json[val]+'</p>'); 
      $("#"+i).append("<p><br/></p>"); 
      $('#load').empty(); 
      processFilms(film, i+1); 
     } 
    ); 
    } 
} 

processFilms(['Fast', 'Nemo']); 

注意:其他方法是使用回调函数为你做递归调用。

此外,您可以确保'j'在运行$ .getJSON时不会改变。它是异步的,但'j'不会改变。

for(var j= 0; j< film.length; j++){ 
     (function (j_aux) { 
     $.getJSON("http://www.omdbapi.com/?t="+film[j]+"&y=&plot=short&r=json", function(json) { 
       console.log("processing "+j_aux+" : "+film[j_aux]); 
       $("#info").append("<div id="+j_aux+" class='for-info'></div>"); 
       $('#load').empty(); 
       for(val in json) 
        $("#"+j_aux).append('<p>'+val+' --> '+json[val]+'</p>'); 
       $("#"+j_aux).append("<p><br/></p>"); 
     }); 
     })(j); 
} 
+0

整个问题是,** j **在** getJSON **里面改变。没有承诺,我不得不在** getJSON **内部手动设置'j = 0',并在块结束时增加它。你认为这种方式以后可能会导致我现在无法预测的问题吗? – user3762742

+0

如果在getJSON中设置j = 0,那么在该请求中'j'为0。但我明白,你希望'j'值是每部电影请求中的索引。如果强制j = 0,并在块的末尾增加'j',那么在所有回调的开始处,j值将为0.在块的末尾增加'j',在下一次调用时,'j'无动于衷, j'back将被赋值为0,并且在所有回调期间值不会改变。也许j只能在第一个请求中为0 – fbohorquez

4

因为$.getJSON是异步的,不能保证之前,其他

这样一个将结束,创建和分配div$.getJSON

for(var i= 0; i< film.length; i++){ 
    $('#load').html("<h2>LOadiNG.....................</h2>"); 

    for(var j= 0; j< film.length; j++){ 
     $("#info").append("<div id="+j+" class='for-info'></div>"); 
     $.getJSON("http://www.omdbapi.com/?t="+film[j]+"&y=&plot=short&r=json", function(json) { 
      for(val in json){ 
       $("#"+j).append('<p>'+val+' --> '+json[val]+'</p>'); 
      } 
      $("#"+j).append("<p><br/></p>"); 
      $('#load').empty(); 
     }); 
    } 
} 
+0

问题仍然存在。但我想,我已经能够明确问题所在。逻辑看起来很好,但问题是循环控制变量** j **。在** getJSON **块之外,** j **按预期工作,但不在内部。实际上,由于某种原因,** j **的值为film.length。异步调用与它有关吗? – user3762742

+0

问题修复。在** getJSON **函数内部使用'if(j == film.length)j = 0;'和'j ++'的块结尾。似乎工作 – user3762742

0

你可以使用CSS来给你换信息类底部的边框和边距,如下所示:

(注意:我使用:not(:last-child)选择器不将分频器应用到最后DIV)

.for-info:not(:last-child) { 
 
    border-bottom: 2px solid black; 
 
    margin-bottom: 10px; 
 
} 
 

 
.for-info { 
 
    height: 40px; 
 
    background-color: #c3c3c3; 
 
}
<div id='movie1' class='for-info'>Some content...</div> 
 
<div id='movie2' class='for-info'>Some content...</div> 
 
<div id='movie2' class='for-info'>Some content...</div>

+0

这是我已经做的事情。我得到的部门,但结果是非常随机的 – user3762742