diff --git a/List.js b/List.js index 625f0ab54..030bb32b1 100644 --- a/List.js +++ b/List.js @@ -442,14 +442,15 @@ function(kernel, declare, listen, has, miscUtil, TouchScroll, hasClass, put){ options = options || {}; var self = this, start = options.start || 0, - row, rows, container; + observers = this.observers, + row, rows, container, observerIndex; if(!beforeNode){ this._lastCollection = results; } if(results.observe){ // observe the results for changes - var observerIndex = this.observers.push(results.observe(function(object, from, to){ + observerIndex = observers.push(results.observe(function(object, from, to){ var firstRow, nextNode, parentNode; // a change in the data took place if(from > -1 && rows[from]){ @@ -503,34 +504,50 @@ function(kernel, declare, listen, has, miscUtil, TouchScroll, hasClass, put){ self._onNotification(rows, object, from, to); }, true)) - 1; } - var rowsFragment = document.createDocumentFragment(); - // now render the results - if(results.map){ - rows = results.map(mapEach, console.error); - if(rows.then){ - return rows.then(whenDone); - } - }else{ - rows = []; - for(var i = 0, l = results.length; i < l; i++){ - rows[i] = mapEach(results[i]); - } - } - var lastRow; + var rowsFragment = document.createDocumentFragment(), + lastRow; + function mapEach(object){ lastRow = self.insertRow(object, rowsFragment, null, start++, options); lastRow.observerIndex = observerIndex; return lastRow; } + function whenError(error){ + if(typeof observerIndex !== "undefined"){ + observers[observerIndex].cancel(); + observers[observerIndex] = 0; + } + if(error){ + throw error; + } + } function whenDone(resolvedRows){ container = beforeNode ? beforeNode.parentNode : self.contentNode; - if(container){ + if(container && container.parentNode && resolvedRows.length){ container.insertBefore(rowsFragment, beforeNode || null); lastRow = resolvedRows[resolvedRows.length - 1]; lastRow && self.adjustRowIndices(lastRow); + }else if(observers[observerIndex]){ + // Remove the observer and don't bother inserting; + // rows are already out of view or there were none to track + whenError(); } return (rows = resolvedRows); } + + // now render the results + if(results.map){ + rows = results.map(mapEach, console.error); + if(rows.then){ + return rows.then(whenDone, whenError); + } + }else{ + rows = []; + for(var i = 0, l = results.length; i < l; i++){ + rows[i] = mapEach(results[i]); + } + } + return whenDone(rows); },