Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Commit

Permalink
refactoring, close a feedback loop
Browse files Browse the repository at this point in the history
  • Loading branch information
Scott J. Miles committed Jun 3, 2014
1 parent ff18cb9 commit c76c414
Showing 1 changed file with 73 additions and 44 deletions.
117 changes: 73 additions & 44 deletions firebase-element.html
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,19 @@ <h3>My Firebase Data</h3>
'ref limit start end': 'requery'
},
locationChanged: function() {
if (this.query) {
this.query.off();
}
// shut-down previous observers (if any)
this.closeQuery();
this.closeObserver();
// connect to db
if (this.location) {
this.ref = new Firebase(this.location);
}
},
requery: function() {
// shut-down previous observers (if any)
this.closeQuery();
this.closeObserver();
// construct new query
var query = this.ref;
if (this.start) {
query = query.startAt(this.start);
Expand All @@ -207,10 +211,8 @@ <h3>My Firebase Data</h3>
this._setData(null);
// data acquisition
this.query.once('value', this.valueLoaded, this);
// server side dynamics
this.query.on('child_added', this.childAdded, this);
this.query.on('child_changed', this.childChanged, this);
this.query.on('child_removed', this.childRemoved, this);
// observe server-side data
this.observeQuery();
},
valueLoaded: function(snapshot) {
if (this.ref.name() !== snapshot.name()) {
Expand All @@ -221,8 +223,29 @@ <h3>My Firebase Data</h3>
this._setData(snapshot.val() || {});
this.dataChange();
},
_setData: function(data) {
this.closeObserver();
this.data = this._data = data;
this.observeData();
},
//
// server-side data-observation
//
observeQuery: function() {
// server side dynamics
this.query.on('child_added', this.childAdded, this);
this.query.on('child_changed', this.childChanged, this);
this.query.on('child_removed', this.childRemoved, this);
},
closeQuery: function() {
if (this.query) {
this.query.off();
}
},
//
// client-side data-observation
//
observeData: function() {
// client-side dynamics
if (this.data instanceof Array) {
this.observer = new ArrayObserver(this.data);
this.observer.open(this.observeArray.bind(this));
Expand All @@ -231,82 +254,88 @@ <h3>My Firebase Data</h3>
this.observer.open(this.observeObject.bind(this));
}
},
_setData: function(data) {
this.closeObserver();
this.data = this._data = data;
this.observeData();
closeObserver: function() {
if (this.observer) {
this.observer.close();
this.observer = null;
}
},
dataChanged: function() {
if (this._data !== this.data) {
this._setData(this.data);
this.commit();
}
},
closeObserver: function() {
discardObservations: function() {
if (this.observer) {
this.observer.close();
this.observer = null;
this.observer.discardChanges();
}
},
deliverObservations: function() {
if (this.observer) {
this.observer.deliver();
}
},
//
// server-side effects
//
childAdded: function(snapshot) {
// ignore initial adds, we'll take the 'value' instead
if (this.data) {
this.updateData(snapshot);
}
this.log && console.log('child-added ' + snapshot.name());
if (this.childEvents) {
this.fire('child-added', {name: snapshot.name(), value: snapshot.val()});
this.modulateData('updateData', snapshot);
}
this.childEvent('child-added', snapshot);
},
childChanged: function(snapshot) {
this.updateData(snapshot);
this.log && console.log('child-changed ' + snapshot.name());
if (this.childEvents) {
this.fire('child-changed', {name: snapshot.name(), value: snapshot.val()});
}
this.modulateData('updateData', snapshot);
this.childEvent('child-changed', snapshot);
},
childRemoved: function(snapshot) {
this.removeData(snapshot.name());
this.log && console.log('child-removed ' + snapshot.name());
this.modulateData('removeData', snapshot);
this.childEvent('child-removed', snapshot);
},
childEvent: function(kind, snapshot) {
this.log && console.log(kind + snapshot.name());
if (this.childEvents) {
this.fire('child-removed', {name: snapshot.name(), value: snapshot.val()});
this.fire(kind, {name: snapshot.name(), value: snapshot.val()});
}
},
modulateData: function(operation, snapshot) {
// handle any pending observations
this.deliverObservations();
this[operation](snapshot);
this.dataChange();
// discard any observations so we don't send this value back to the
// server, it may already be stale from the server's perspective
this.discardObservations();
},
updateData: function(snapshot) {
this.data[snapshot.name()] = snapshot.val();
//this.discardObservations();
this.dataChange();
},
removeData: function(key) {
removeData: function(snapshot) {
var key = snapshot.name();
if (this.data instanceof Array) {
this.data.splice(key, 1);
} else {
delete this.data[key];
}
//this.discardObservations();
this.dataChange();
},
dataChange: function() {
this.job('change', function() {
//this.job('change', function() {
this.keys = this.data ? Object.keys(this.data) : [];
this.fire('data-change');
});
//});
},
//
// client-side effects
discardObservations: function() {
if (this.observer) {
this.observer.discardChanges();
}
},
//
observeArray: function(splices) {
//console.warn('observeArray');
// TODO(sjmiles): arrays are nasty because simple insertions/deletions
// cause changes to ripple through keys
this.commit();
},
observeObject: function(added, removed, changed, getOldValueFn) {
//console.warn('observeObject');
// client-side dynamics
var ctrlr = this;
Object.keys(added).forEach(function(property) {
Expand All @@ -324,6 +353,9 @@ <h3>My Firebase Data</h3>
this.log && console.log('commitProperty ' + key);
this.ref.child(key).set(this.data[key]);
},
remove: function(key) {
this.ref.child(key).remove();
},
commit: function() {
this.log && console.log('commit');
this.ref.set(this.data);
Expand All @@ -335,9 +367,6 @@ <h3>My Firebase Data</h3>
this.ref.push(item);
}
this.dataChange();
},
remove: function(key) {
this.ref.child(key).remove();
}
});
</script>
Expand Down

0 comments on commit c76c414

Please sign in to comment.