This repository has been archived by the owner on Feb 22, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 248
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(ng-repeat): refactor the fix for #1015
- Loading branch information
1 parent
68c3e80
commit f6187ae
Showing
1 changed file
with
63 additions
and
66 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -131,91 +131,88 @@ class NgRepeat { | |
|
||
_watch = _scope.watch( | ||
_listExpr, | ||
(CollectionChangeRecord changes, _) { | ||
_onChange((changes is CollectionChangeRecord) ? changes : null); | ||
(changes, _) { | ||
if (changes is CollectionChangeRecord && changes != null) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
vicb
Author
Contributor
|
||
_onCollectionChange(changes); | ||
} else if (_rows != null) { | ||
_rows.forEach((row) { | ||
row.scope.destroy(); | ||
_viewPort.remove(row.view); | ||
}); | ||
_rows = null; | ||
} | ||
}, | ||
collection: true, | ||
formatters: formatters | ||
); | ||
} | ||
|
||
// Computes and executes DOM changes when the item list changes | ||
void _onChange(CollectionChangeRecord changes) { | ||
final iterable = (changes == null) ? const [] : changes.iterable; | ||
final int length = (changes == null) ? 0 : changes.length; | ||
void _onCollectionChange(CollectionChangeRecord changes) { | ||
final int length = changes.length; | ||
final rows = new List<_Row>(length); | ||
final changeFunctions = new List<Function>(length); | ||
final removedIndexes = <int>[]; | ||
final int domLength = _rows == null ? 0 : _rows.length; | ||
final leftInDom = new List.generate(domLength, (i) => domLength - 1 - i); | ||
var domIndex; | ||
|
||
var addRow = (int index, value, View previousView) { | ||
var childContext = _updateContext(new PrototypeMap(_scope.context), index, | ||
length)..[_valueIdentifier] = value; | ||
var childScope = _scope.createChild(childContext); | ||
var view = _boundViewFactory(childScope); | ||
var nodes = view.nodes; | ||
rows[index] = new _Row(_generateId(index, value, index)) | ||
..view = view | ||
..scope = childScope | ||
..nodes = nodes | ||
..startNode = nodes.first | ||
..endNode = nodes.last; | ||
_viewPort.insert(view, insertAfter: previousView); | ||
}; | ||
Function addFn, moveFn, removeFn; | ||
|
||
// todo(vicb) refactor once GH-774 gets fixed | ||
if (_rows == null) { | ||
_rows = new List<_Row>(length); | ||
for (var i = 0; i < length; i++) { | ||
changeFunctions[i] = (index, previousView) { | ||
addRow(index, iterable.elementAt(i), previousView); | ||
}; | ||
} | ||
addFn = changes.forEachItem; | ||
moveFn = (_) {}; | ||
removeFn = (_) {}; | ||
} else { | ||
if (changes == null) { | ||
_rows.forEach((row) { | ||
row.scope.destroy(); | ||
_viewPort.remove(row.view); | ||
}); | ||
leftInDom.clear(); | ||
} else { | ||
changes.forEachRemoval((CollectionChangeItem removal) { | ||
var index = removal.previousIndex; | ||
var row = _rows[index]; | ||
row.scope.destroy(); | ||
_viewPort.remove(row.view); | ||
leftInDom.removeAt(domLength - 1 - index); | ||
}); | ||
addFn = changes.forEachAddition; | ||
moveFn = changes.forEachMove; | ||
removeFn = changes.forEachRemoval; | ||
} | ||
|
||
changes.forEachAddition((CollectionChangeItem addition) { | ||
changeFunctions[addition.currentIndex] = (index, previousView) { | ||
addRow(index, addition.item, previousView); | ||
}; | ||
}); | ||
removeFn((CollectionChangeItem removal) { | ||
var index = removal.previousIndex; | ||
var row = _rows[index]; | ||
row.scope.destroy(); | ||
_viewPort.remove(row.view); | ||
leftInDom.removeAt(domLength - 1 - index); | ||
}); | ||
|
||
changes.forEachMove((CollectionChangeItem move) { | ||
var previousIndex = move.previousIndex; | ||
var value = move.item; | ||
changeFunctions[move.currentIndex] = (index, previousView) { | ||
var previousRow = _rows[previousIndex]; | ||
var childScope = previousRow.scope; | ||
var childContext = _updateContext(childScope.context, index, length); | ||
if (!identical(childScope.context[_valueIdentifier], value)) { | ||
childContext[_valueIdentifier] = value; | ||
} | ||
rows[index] = _rows[previousIndex]; | ||
// Only move the DOM node when required | ||
if (domIndex < 0 || leftInDom[domIndex] != previousIndex) { | ||
_viewPort.move(previousRow.view, moveAfter: previousView); | ||
leftInDom.remove(previousIndex); | ||
} | ||
domIndex--; | ||
}; | ||
}); | ||
} | ||
} | ||
addFn((CollectionChangeItem addition) { | ||
changeFunctions[addition.currentIndex] = (index, previousView) { | ||
var childContext = _updateContext(new PrototypeMap(_scope.context), index,length) | ||
..[_valueIdentifier] = addition.item; | ||
var childScope = _scope.createChild(childContext); | ||
var view = _boundViewFactory(childScope); | ||
var nodes = view.nodes; | ||
rows[index] = new _Row(_generateId(index, addition.item, index)) | ||
..view = view | ||
..scope = childScope | ||
..nodes = nodes | ||
..startNode = nodes.first | ||
..endNode = nodes.last; | ||
_viewPort.insert(view, insertAfter: previousView); | ||
}; | ||
}); | ||
|
||
moveFn((CollectionChangeItem move) { | ||
var previousIndex = move.previousIndex; | ||
var value = move.item; | ||
changeFunctions[move.currentIndex] = (index, previousView) { | ||
var previousRow = _rows[previousIndex]; | ||
var childScope = previousRow.scope; | ||
var childContext = _updateContext(childScope.context, index, length); | ||
if (!identical(childScope.context[_valueIdentifier], value)) { | ||
childContext[_valueIdentifier] = value; | ||
} | ||
rows[index] = _rows[previousIndex]; | ||
// Only move the DOM node when required | ||
if (domIndex < 0 || leftInDom[domIndex] != previousIndex) { | ||
_viewPort.move(previousRow.view, moveAfter: previousView); | ||
leftInDom.remove(previousIndex); | ||
} | ||
domIndex--; | ||
}; | ||
}); | ||
|
||
var previousView = null; | ||
domIndex = leftInDom.length - 1; | ||
|
This is changing the behaviour of the directive. Could you add a test?