Created
December 23, 2013 08:21
-
-
Save marshallswain/8093413 to your computer and use it in GitHub Desktop.
Firebase CanJS LIst Controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var FirebaseListController = can.Control.extend({ | |
defaults: { | |
// The main Firebase URL, including the trailing slash. | |
baseURL: 'https://bchm.firebaseIO.com/', | |
// The location of the list of data in Firebase. | |
location: "test_list", | |
// The HTML attribute that should be added to a template element in the list. | |
// It will need to be unique and will contain a single value, like an id, not a class. | |
// unused because I can't get can.Mustache to work with it right now. Keeps printing __!!__ | |
// firebaseKeyName: "data-firebasekey", | |
// The HTML tag that will contain the data-firebasekey attribute. | |
tag: "tr", | |
// Each can.Map in the list will be available at can.data('firebaseData') unless | |
// this is changed. | |
firebaseDataKey:"firebaseData", | |
// The name of the can.List | |
listName: "list" | |
} | |
},{ | |
'init': function(element){ | |
var self = this; | |
self.newItems = false; | |
// Create empty list to populate. | |
self.options.list = new can.List(); | |
window.ListMe = self.options.list; | |
// Build a firebaseURL out of the baseURL and location. | |
self.options.firebaseURL = self.options.baseURL + self.options.location; | |
// Get items from Firebase. | |
self.firebaseRef = new Firebase(self.options.firebaseURL); | |
// TODO: Use prevChildName for proper sorting. | |
// Upon Firebase child_added, push the child to the can.List. | |
self.firebaseRef.on('child_added', function(snapshot, prevChildName){ | |
if (!self.newItems) return; | |
// Get the data from the Firebase snapshot. | |
var data = snapshot.val(); | |
// Add the firebasekey to the data so template has access to it. | |
data.firebasekey = snapshot.name(); | |
// Add each child_added to the user list. | |
self.options.list.push(data); | |
}, function(error){console.log(error)}); | |
self.firebaseRef.once('value', function(snapshot, prevChildName){ | |
// This keeps 'child_added' from firing until the initial 'value' is done. | |
self.newItems = true; | |
// Prepare an array to push into self.options.list all at once. | |
// It's faster to set an array into a can.List than it is to use can.List.push(item) | |
var dataArray = new Array(); | |
snapshot.forEach(function(childSnapshot) { | |
data = childSnapshot.val(); | |
data.firebasekey = childSnapshot.name(); | |
// Add to the array. | |
dataArray.push(data); | |
}); | |
// Set array into the can.List. | |
self.options.list.attr(dataArray); | |
}, function(error){console.log(error)}); | |
self.addListeners(); | |
}, | |
// Add other listeners after the inital data has loaded. | |
'addListeners': function(){ | |
var self = this; | |
// Upon Firebase child_changed, update the changes to the corresponding can.Map. | |
self.firebaseRef.on('child_changed', function(snapshot, prevChildName){ | |
var data = snapshot.val(); | |
data.firebasekey = snapshot.name(); | |
// Find the matching element / data | |
var query = self.options.tag+'[data-firebasekey="'+ data.firebasekey +'"]'; | |
var item = self.element.find(query).data("firebaseData"); | |
// Overwrite all data in the can.Map. | |
item.attr(data, true); | |
}); | |
// Upon Firebase child_removed, remove from the can.List. | |
self.firebaseRef.on('child_removed', function(snapshot, prevChildName){ | |
var data = snapshot.val(); | |
// Find the matching element / data | |
var query = self.options.tag+'[data-firebasekey="'+ snapshot.name() +'"]'; | |
var item = self.element.find(query).data("firebaseData"); | |
// Remove the item from the list. | |
var position = self.options.list.indexOf(item); | |
self.options.list.splice(position, 1); | |
}); | |
// Upon adding to the can.List, add it to Firebase. | |
self.options.list.bind('add', function(ev, newElement, index) { | |
// console.log(ev, newElements, index); | |
// var newRef = new Firebase(self.options.firebaseURL).push(); | |
// if (newElements != undefined) { | |
// console.log(newElement); | |
// newElement.attr('name', "moose"); | |
// newRef.set(data); | |
// }; | |
}); | |
// Upon editing a can.List item, update Firebase. | |
self.options.list.bind('change', function(ev, index, how, newVal, oldVal) { | |
// console.log(ev + ', ' + index + ', ' + how + ', ' + newVal + ', ' + oldVal); | |
}); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment