diff --git a/firebase-query.html b/firebase-query.html
index 41246bb..d197709 100644
--- a/firebase-query.html
+++ b/firebase-query.html
@@ -280,12 +280,14 @@
__queryChanged: function(query, oldQuery) {
if (oldQuery) {
+ oldQuery.off('value', this.__onFirebaseValue, this);
oldQuery.off('child_added', this.__onFirebaseChildAdded, this);
oldQuery.off('child_removed', this.__onFirebaseChildRemoved, this);
oldQuery.off('child_changed', this.__onFirebaseChildChanged, this);
oldQuery.off('child_moved', this.__onFirebaseChildMoved, this);
this.syncToMemory(function() {
+ this.__map = {};
this.set('data', this.zeroValue);
});
}
@@ -299,6 +301,16 @@
}
this._onOnce = true;
+
+ /* We want the value callback to batch load the initial data,
+ * then let child_added take over for subsequent changes.
+ */
+ this.__initialLoadDone = false;
+
+ /* Don't use query.once() as we need to be able to cancel
+ * the callback if the query changes
+ */
+ query.on('value', this.__onFirebaseValue, this.__onError, this);
query.on('child_added', this.__onFirebaseChildAdded, this.__onError, this);
query.on('child_removed', this.__onFirebaseChildRemoved, this.__onError, this);
query.on('child_changed', this.__onFirebaseChildChanged, this.__onError, this);
@@ -317,17 +329,38 @@
return -1;
},
+ __onFirebaseValue: function(snapshot) {
+ if (snapshot.hasChildren()) {
+ var data = [];
+ snapshot.forEach(function(childSnapshot) {
+ var key = childSnapshot.key;
+ var value = this.__valueWithKey(key, childSnapshot.val())
+ this.__map[key] = value;
+ data.push(value)
+ }.bind(this))
+
+ this.set('data', data);
+ }
+
+ /* Now let child_added deal with subsequent changes */
+ this.query.off('value', this.__onFirebaseValue, this);
+ this.__initialLoadDone = true;
+ },
+
__onFirebaseChildAdded: function(snapshot, previousChildKey) {
var key = snapshot.key;
- var value = snapshot.val();
- var previousChildIndex = this.__indexFromKey(previousChildKey);
- this._log('Firebase child_added:', key, value);
+ if (this.__initialLoadDone) {
+ var value = snapshot.val();
+ var previousChildIndex = this.__indexFromKey(previousChildKey);
- value = this.__snapshotToValue(snapshot);
+ this._log('Firebase child_added:', key, value);
- this.__map[key] = value;
- this.splice('data', previousChildIndex + 1, 0, value);
+ value = this.__snapshotToValue(snapshot);
+
+ this.__map[key] = value;
+ this.splice('data', previousChildIndex + 1, 0, value);
+ }
},
__onFirebaseChildRemoved: function(snapshot) {
@@ -402,10 +435,7 @@
}
},
- __snapshotToValue: function(snapshot) {
- var key = snapshot.key;
- var value = snapshot.val();
-
+ __valueWithKey: function(key, value) {
var leaf = typeof value !== 'object';
if (leaf) {
@@ -414,6 +444,13 @@
value.$key = key;
}
return value;
+ },
+
+ __snapshotToValue: function(snapshot) {
+ var key = snapshot.key;
+ var value = snapshot.val();
+
+ return this.__valueWithKey(key, value);
}
});
})();