2012-11-13 41 views
0

我試圖顯示Phonegap(科爾多瓦)應用程序中的項目列表,其中每個項目需要額外的查詢。兩個查詢,其中第二個依賴於第一個

爲了簡單起見,我會用一個例子來解釋它。假設一個student可以有多個course和一個course可以有許多student(多對多),我想顯示一個列表顯示學生註冊到哪些課程。就像這樣:

  • Student1:course1,course2
  • STUDENT2:course1,course3,當然5
  • 學生三:course2
  • ...

首先,我需要一個查詢遍歷所有學生,然後爲每個學生查詢數據庫以瞭解學生註冊的課程:

db.transaction(function(tx) { 
    tx.executeSql('SELECT `student`.`id`, `student`.`name` ' + 
      'FROM `student`', 
      [], 
      function(tx, resultSet) { 
       for(var i = 0; i < resultSet.rows.length; i++) { 
        tx.executeSql('SELECT `course`.`name` ' + 
          'FROM `student_has_course` ' + 
          'INNER JOIN `student` ON `student_has_course`.`student_id` = `student`.`id` ' + 
          'INNER JOIN `course` ON `student_has_course`.`course_id` = `course`.`id` ' + 
          'WHERE `student`.`id` = ?' 
          [resultSet.rows.item(i).id], 
          function(tx2, resultSet2) { 
           // TODO 
          }); 
       } 
      }); 
}, function(err) { 
    showError('Error getting students from the DB (' + err.message + ')'); 
}, function() { 
    alert('success!'); 
}); 

現在,問題是在第二個回調函數中(「TODO」是),我沒有引用任何前一個查詢的數據。例如,如果我嘗試alert(i)它會提醒76,這相當於resultSet.rows.length。這顯然是因爲兩個回調函數都是異步的。我怎麼能克服這個問題並按照上面所示打印列表?

任何幫助極大的讚賞。

回答

2

您應該能夠通過附加屬性回調函數本身來解決這個問題如下:

cb = function cbfunc() { 
    doStuffWith(cbfunc.data) 
} 
cb.data = ... // whatever 
tx.executeSQL(..., cb) 

不過,我會三思而後行,如果我可以通過一個單一的生產預期的結果避免了二次回調查詢。在這種情況下:

select student.id, student.name, course.name from student 
    inner join student_has_course on student.id = student_has_course.student_id 
    inner join course on student_has_course.course_id = course.id 
     order by student.id; 

,並在循環,比較與一個從以前的迭代知道何時打印新行和新的學生姓名,以獲得您想要的輸出格式的student.id。

+0

謝謝@jop。這只是一個解決方法,但我正在尋找一種通用的解決方案,在我看到的任何情況下都可以工作 – satoshi

+0

。我編輯它以提供更通用的解決方案,即使對於此特定示例,單個SQL仍然看起來更好。 – jop

+0

謝謝,解決方案工作:) – satoshi

相關問題