2017-05-21 138 views
0

我想從我的數據庫檢索數據。我的代碼創建一個空數組,並在每次添加時向其添加一個子對象。然後創建列表(忽略MDL類)並將其添加到HTML文檔中。無法檢索到JavaScript數組的firebase快照數據

<script> 
    // get emergencies to array 
    var firebaseRef = firebase.database().ref('Incidents'); 
    var emergencies = []; 
    // var emergencies = ['Test', 'Test 2', 'Test 3']; 

    firebaseRef.on('child_added', function(snap) { 
     snap.forEach(function (childSnap) { 
      console.log(childSnap.val()); 
      emergencies.push(childSnap.val()); 
     }); 
    }); 

    var opentag = '<ul class="mdl-list" id="emergenciesList">', 
    closetag = '</ul>', 
    array = []; 

    for (i = 1; i <= emergencies.length; i++) { 
     array[i] = '<li class="mdl-list__item">' + emergencies[i] + '</li>'; 
    } 

    var newArray = array.join(" "); 

    document.getElementById('foo').innerHTML = opentag + newArray + closetag; 
</script> 

奇怪的是,在執行console.log()語句,檢索數據完全正常,但字符串操作後,newArray是不確定的。幫幫我!

回答

1

問題是由您訂購代碼的方式造成的。線的執行順序不是你想象的。這是最簡單的,看看這個,如果你將其降低到這一點:

var firebaseRef = firebase.database().ref('Incidents'); 

console.log("Before database loading started"); 
firebaseRef.on('child_added', function(snap) { 
    console.log("In child_added"); 
}); 
console.log("After database loading started"); 

現在該記錄將被寫入的順序是:

之前數據庫加載啓動

數據庫加載啓動

in child_added

這可能不是您所期望的。日誌按此順序顯示的原因是Firebase異步加載數據。因此,當on('child_added'開始加載數據時,可能需要一段時間才能從Firebase服務器獲取該數據。瀏覽器不會等待數據(這會阻止用戶與應用程序交互的能力),而是繼續在該塊之後執行語句。然後,當數據可用時,它會調用您的回調函數。

處理異步性的常見方法是重新組合問題。現在您的代碼被寫爲「首先加載數據,然後將其添加到HTML」。嘗試改爲「開始加載數據,當數據可用時,將其添加到HTML」。這翻譯成此代碼:

var firebaseRef = firebase.database().ref('Incidents'); 

firebaseRef.on('child_added', function(snapshot) { 
    var ul = document.getElementById("emergenciesList"); 
    if (!ul) { 
     document.getElementById('foo').innerHTML = '<ul class="mdl-list" id="emergenciesList"></ul>'; 
     ul = document.getElementById("emergenciesList"); 
    } 
    var li = document.createElement("li"); 
    li.classList.append("mdl-list__item"); // or: li.className = "mdl-list__item" 
    li.id = snapshot.key; 
    li.innerText = snapshot.val(); 
    ul.appendChild(li); 
}); 

我刪除了快照上的循環,因爲我不確定它是否需要,它使代碼複雜化。如果你的數據結構需要循環,你可以將它添加回原來的位置。

+0

非常感謝!這很有意義。有一個問題,但它仍然不起作用;我現在收到一個錯誤,「li.classList.append」不是一個函數。我也嘗試過「li.className」。這是爲什麼? – wasimsandhu

+0

有趣。 [Element.classList](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList)[相對良好的支持](http://caniuse.com/#feat=classlist) DOM方法。我在評論中添加了一個更兼容的備選方案。 –