Skip to content
Browse files

Reduce keySplices to minimum change set before notifying. Fixes #2261

  • Loading branch information...
1 parent 7497729 commit f74d07245ffadcae4a2e060161eb537362c6b007 @kevinpschaaf kevinpschaaf committed
Showing with 41 additions and 32 deletions.
  1. +27 −21 src/lib/collection.html
  2. +14 −11 src/lib/template/dom-repeat.html
View
48 src/lib/collection.html
@@ -106,32 +106,38 @@
},
_applySplices: function(splices) {
- var keySplices = [];
- for (var i=0; i<splices.length; i++) {
- var j, o, key, s = splices[i];
- // Removed keys
- var removed = [];
- for (j=0; j<s.removed.length; j++) {
- o = s.removed[j];
- key = this.remove(o);
+ // Dedupe added and removed keys to a final added/removed map
+ var keyMap = {}, key, i;
+ splices.forEach(function(s) {
+ s.addedKeys = [];
+ for (i=0; i<s.removed.length; i++) {
+ key = this.getKey(s.removed[i]);
+ keyMap[key] = keyMap[key] ? null : -1;
+ }
+ for (i=0; i<s.addedCount; i++) {
+ var item = this.userArray[s.index + i];
+ key = this.getKey(item);
+ key = (key === undefined) ? this.add(item) : key;
+ keyMap[key] = keyMap[key] ? null : 1;
+ s.addedKeys.push(key);
+ }
+ }, this);
+ // Convert added/removed key map to added/removed arrays
+ var removed = [];
+ var added = [];
+ for (var key in keyMap) {
+ if (keyMap[key] < 0) {
+ this.removeKey(key);
removed.push(key);
}
- // Added keys
- var added = [];
- for (j=0; j<s.addedCount; j++) {
- o = this.userArray[s.index + j];
- key = this.add(o);
+ if (keyMap[key] > 0) {
added.push(key);
}
- // Record splice
- keySplices.push({
- index: s.index,
- removed: removed,
- removedItems: s.removed,
- added: added
- });
}
- return keySplices;
+ return [{
+ removed: removed,
+ added: added
+ }];
}
};
View
25 src/lib/template/dom-repeat.html
@@ -268,11 +268,13 @@
this._error(this._logf('dom-repeat', 'expected array for `items`,' +
' found', this.items));
}
- this._splices = [];
+ this._keySplices = [];
+ this._indexSplices = [];
this._needFullRefresh = true;
this._debounceTemplate(this._render);
} else if (change.path == 'items.splices') {
- this._splices = this._splices.concat(change.value.keySplices);
+ this._keySplices = this._keySplices.concat(change.value.keySplices);
+ this._indexSplices = this._indexSplices.concat(change.value.indexSplices);
this._debounceTemplate(this._render);
} else { // items.*
// slice off 'items.' ('items.'.length == 6)
@@ -303,10 +305,10 @@
},
/**
- * Forces the element to render its content. Normally rendering is
- * asynchronous to a provoking change. This is done for efficiency so
- * that multiple changes trigger only a single render. The render method
- * should be called if, for example, template rendering is required to
+ * Forces the element to render its content. Normally rendering is
+ * asynchronous to a provoking change. This is done for efficiency so
+ * that multiple changes trigger only a single render. The render method
+ * should be called if, for example, template rendering is required to
* validate application state.
*/
render: function() {
@@ -324,17 +326,18 @@
this._needFullRefresh = false;
} else {
if (this._sortFn) {
- this._applySplicesUserSort(this._splices);
+ this._applySplicesUserSort(this._keySplices);
} else {
if (this._filterFn) {
// TODK(kschaaf): Filtering using array sort takes slow path
this._applyFullRefresh();
} else {
- this._applySplicesArrayOrder(this._splices);
+ this._applySplicesArrayOrder(this._indexSplices);
}
}
}
- this._splices = [];
+ this._keySplices = [];
+ this._indexSplices = [];
// Update final _keyToInstIdx and instance indices
var keyToIdx = this._keyToInstIdx = {};
for (var i=0; i<this._instances.length; i++) {
@@ -511,10 +514,10 @@
}
this._instances.splice(s.index, s.removed.length);
// Insert placeholders for new rows
- for (var i=0; i<s.added.length; i++) {
+ for (var i=0; i<s.addedKeys.length; i++) {
var inst = {
isPlaceholder: true,
- key: s.added[i]
+ key: s.addedKeys[i]
};
this._instances.splice(s.index + i, 0, inst);
}

0 comments on commit f74d072

Please sign in to comment.
Something went wrong with that request. Please try again.