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); } }); })();