Skip to content

Commit

Permalink
refactor(ng-repeat): refactor the fix for dart-archive#1015
Browse files Browse the repository at this point in the history
  • Loading branch information
vicb authored and [email protected] committed Jun 4, 2014
1 parent 68c3e80 commit f6187ae
Showing 1 changed file with 63 additions and 66 deletions.
129 changes: 63 additions & 66 deletions lib/directive/ng_repeat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
_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;
Expand Down

0 comments on commit f6187ae

Please sign in to comment.