function Path(feedId, factory, urlOrRef, initialCb, filterPath) {
            var subs = [];
            var pathRef = angular.isArray(urlOrRef)? urlOrRef[0] : urlOrRef;
            if (typeof pathRef == "string") {
               pathRef = new Firebase(pathRef);
            }

            this._init = function() {
               subs.push(['child_added', pathRef.on('child_added', function(ss, prevId) {
                  var id = ss.name();
                  var item = new AngularFireItem(factory, ss, getIndex(prevId));
                  if( filterMap.isFiltered(item.$feed, item.$id) ) {
                     filteredArticles[id] = [item, prevId];
                  }
                  else {
                     addChild(item, prevId);
                  }
               }, function(e) { $log.debug(e); })]);

               subs.push(['child_removed', pathRef.on('child_removed', function(snap) {
                  delete filteredArticles[snap.name()];
                  removeChild(snap.name());
               }, function(e) { $log.warn(e); })]);

               subs.push(['child_changed', pathRef.on('child_changed', function(snap, prevId) {
                  var id = snap.name();
                  if( filteredArticles[id] ) {
                     _.extend(filteredArticles[id][0], snap.val());
                     filteredArticles[id][0].$priority = snap.getPriority();
                  }
                  else if( indexes.hasOwnProperty(id) ) {
                     var index = indexes[id];
                     var newIndex = getIndex(prevId);
                     updateChild(index, factory(snap, index), snap.getPriority());
                     if (newIndex !== index) {
                        moveChild(index, newIndex, collection[index]);
                     }
                  }
               })]);

               subs.push(['child_moved', pathRef.on('child_moved', function(snap, prevId) {
                  var id = snap.name();
                  if( filteredArticles[id] ) {
                     filteredArticles[id].$priority = snap.getPriority();
                  }
                  else if( indexes.hasOwnProperty(id) ) {
                     var oldIndex = indexes[id];
                     var newIndex = getIndex(prevId);
                     var item = collection[oldIndex];
                     item.$priority = snap.getPriority();
                     moveChild(oldIndex, newIndex, item);
                  }
               })]);
            };

            if( filterPath ) {
               filterMap.addPath(filterPath);
               filterPath.once('value', this._init.bind(this));
            }
            else {
               this._init();
            }

            // putting this at the end makes performance appear considerably faster
            // since child_added callbacks start immediately instead of after entire
            // data set is loaded on server
            if (initialCb && typeof initialCb == 'function') {
               pathRef.once('value', initialCb);
            }

            this.dispose = function() {
               filterPath && filterMap.removePath(filterPath.ref().name());
               _.each(subs, function(s) {
                  pathRef.off(s[0], s[1]);
               });
               pathRef = null;
               //todo this will not work if using two refs that access the same path
               //todo which seems unlikely but remotely possible
               angular.forEach(collection.slice(), function(item) {
                  if( item.$feed === feedId ) {
                     removeChild(item.$id);
                  }
               });
            };
         }
/**
          * A single Firebase path from which data objects are going to be aggregated into the Collection. Each
          * item in the path is converted using  into an object by using opts.factory.
          *
          * The urlOrRef can be an array so that you can pass a unique id, which will be used later if dispose() is called
          * on the path. This is necessary when using limit() because Firebase.toString() no longer returns a unique path.
          *
          * @param {Function} factory generates the data for each entry in this path
          * @param {String|Firebase|Array} urlOrRef
          * @param {Firebase|String} filterPath a path whose ids match ids in `path` and remove values from results
          * @param {Function} [initialCb]
          * @constructor
          */
A single Firebase path from which data objects are going to be aggregated into the Collection. Each
item in the path is converted using  into an object by using opts.factory.

The urlOrRef can be an array so that you can pass a unique id, which will be used later if dispose() is called
on the path. This is necessary when using limit() because Firebase.toString() no longer returns a unique path.


A single Firebase path from which data objects are going to be aggregated into the Collection . Each item in the path is converted using into an object by using opts . factory . The urlOrRef can be an array so that you can pass a unique id which will be used later if dispose () is called on the path . This is necessary when using limit () because Firebase . toString () no longer returns a unique path .
function Path(feedId, factory, urlOrRef, initialCb, filterPath) {
            var subs = [];
            var pathRef = angular.isArray(urlOrRef)? urlOrRef[0] : urlOrRef;
            if (typeof pathRef == "string") {
               pathRef = new Firebase(pathRef);
            }
            this._init = function() {
               subs.push(['child_added', pathRef.on('child_added', function(ss, prevId) {
                  var id = ss.name();
                  var item = new AngularFireItem(factory, ss, getIndex(prevId));
                  if( filterMap.isFiltered(item.$feed, item.$id) ) {
                     filteredArticles[id] = [item, prevId];
                  }
                  else {
                     addChild(item, prevId);
                  }
               }, function(e) { $log.debug(e); })]);
               subs.push(['child_removed', pathRef.on('child_removed', function(snap) {
                  delete filteredArticles[snap.name()];
                  removeChild(snap.name());
               }, function(e) { $log.warn(e); })]);
               subs.push(['child_changed', pathRef.on('child_changed', function(snap, prevId) {
                  var id = snap.name();
                  if( filteredArticles[id] ) {
                     _.extend(filteredArticles[id][0], snap.val());
                     filteredArticles[id][0].$priority = snap.getPriority();
                  }
                  else if( indexes.hasOwnProperty(id) ) {
                     var index = indexes[id];
                     var newIndex = getIndex(prevId);
                     updateChild(index, factory(snap, index), snap.getPriority());
                     if (newIndex !== index) {
                        moveChild(index, newIndex, collection[index]);
                     }
                  }
               })]);
               subs.push(['child_moved', pathRef.on('child_moved', function(snap, prevId) {
                  var id = snap.name();
                  if( filteredArticles[id] ) {
                     filteredArticles[id].$priority = snap.getPriority();
                  }
                  else if( indexes.hasOwnProperty(id) ) {
                     var oldIndex = indexes[id];
                     var newIndex = getIndex(prevId);
                     var item = collection[oldIndex];
                     item.$priority = snap.getPriority();
                     moveChild(oldIndex, newIndex, item);
                  }
               })]);
            };
            if( filterPath ) {
               filterMap.addPath(filterPath);
               filterPath.once('value', this._init.bind(this));
            }
            else {
               this._init();
            }
            if (initialCb && typeof initialCb == 'function') {
               pathRef.once('value', initialCb);
            }
            this.dispose = function() {
               filterPath && filterMap.removePath(filterPath.ref().name());
               _.each(subs, function(s) {
                  pathRef.off(s[0], s[1]);
               });
               pathRef = null;
               angular.forEach(collection.slice(), function(item) {
                  if( item.$feed === feedId ) {
                     removeChild(item.$id);
                  }
               });
            };
         }
function Path ( feedId , factory , urlOrRef , initialCb , filterPath ) { var subs = [ ] ; var pathRef = angular . isArray ( urlOrRef ) ? urlOrRef [ 0 ] : urlOrRef ; if ( typeof pathRef == "string" ) { pathRef = new Firebase ( pathRef ) ; } this . _init = function ( ) { subs . push ( [ 'child_added' , pathRef . on ( 'child_added' , function ( ss , prevId ) { var id = ss . name ( ) ; var item = new AngularFireItem ( factory , ss , getIndex ( prevId ) ) ; if ( filterMap . isFiltered ( item . $feed , item . $id ) ) { filteredArticles [ id ] = [ item , prevId ] ; } else { addChild ( item , prevId ) ; } } , function ( e ) { $log . debug ( e ) ; } ) ] ) ; subs . push ( [ 'child_removed' , pathRef . on ( 'child_removed' , function ( snap ) { delete filteredArticles [ snap . name ( ) ] ; removeChild ( snap . name ( ) ) ; } , function ( e ) { $log . warn ( e ) ; } ) ] ) ; subs . push ( [ 'child_changed' , pathRef . on ( 'child_changed' , function ( snap , prevId ) { var id = snap . name ( ) ; if ( filteredArticles [ id ] ) { _ . extend ( filteredArticles [ id ] [ 0 ] , snap . val ( ) ) ; filteredArticles [ id ] [ 0 ] . $priority = snap . getPriority ( ) ; } else if ( indexes . hasOwnProperty ( id ) ) { var index = indexes [ id ] ; var newIndex = getIndex ( prevId ) ; updateChild ( index , factory ( snap , index ) , snap . getPriority ( ) ) ; if ( newIndex !== index ) { moveChild ( index , newIndex , collection [ index ] ) ; } } } ) ] ) ; subs . push ( [ 'child_moved' , pathRef . on ( 'child_moved' , function ( snap , prevId ) { var id = snap . name ( ) ; if ( filteredArticles [ id ] ) { filteredArticles [ id ] . $priority = snap . getPriority ( ) ; } else if ( indexes . hasOwnProperty ( id ) ) { var oldIndex = indexes [ id ] ; var newIndex = getIndex ( prevId ) ; var item = collection [ oldIndex ] ; item . $priority = snap . getPriority ( ) ; moveChild ( oldIndex , newIndex , item ) ; } } ) ] ) ; } ; if ( filterPath ) { filterMap . addPath ( filterPath ) ; filterPath . once ( 'value' , this . _init . bind ( this ) ) ; } else { this . _init ( ) ; } if ( initialCb && typeof initialCb == 'function' ) { pathRef . once ( 'value' , initialCb ) ; } this . dispose = function ( ) { filterPath && filterMap . removePath ( filterPath . ref ( ) . name ( ) ) ; _ . each ( subs , function ( s ) { pathRef . off ( s [ 0 ] , s [ 1 ] ) ; } ) ; pathRef = null ; angular . forEach ( collection . slice ( ) , function ( item ) { if ( item . $feed === feedId ) { removeChild ( item . $id ) ; } } ) ; } ; }
A single Firebase path from which data objects are going to be aggregated into the Collection.
A single Firebase path from which data objects are going to be aggregated into the Collection .
// putting this at the end makes performance appear considerably faster // since child_added callbacks start immediately instead of after entire // data set is loaded on server //todo this will not work if using two refs that access the same path //todo which seems unlikely but remotely possible