Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 8c271f7

Browse files
mvuksanochirayuk
authored andcommitted
fix(WatchGroup): Handle watching elements of array that were removed.
Closes #1046
1 parent 14b5a31 commit 8c271f7

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

lib/change_detection/ast_parser.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,14 @@ _operation_logical_and(left, right) => toBool(left) && toBool(right);
193193
_operation_logical_or(left, right) => toBool(left) || toBool(right);
194194

195195
_operation_ternary(condition, yes, no) => toBool(condition) ? yes : no;
196-
_operation_bracket(obj, key) => obj == null ? null : obj[key];
196+
_operation_bracket(obj, key) {
197+
if (obj != null && (
198+
obj is! List || (key is int && key >= 0 && key < obj.length))) {
199+
return obj[key];
200+
} else {
201+
return null;
202+
}
203+
}
197204

198205
class ArrayFn extends FunctionApply {
199206
// TODO(misko): figure out why do we need to make a copy?

test/directive/ng_repeat_spec.dart

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,6 @@ main() {
327327
expect(element.text).toEqual('misko:0|shyam:1|frodo:2|');
328328
});
329329

330-
331330
it(r'should expose iterator position as $first, $middle and $last when iterating over arrays',
332331
() {
333332
element = compile(
@@ -401,6 +400,53 @@ main() {
401400
expect(element.text).toEqual('a|b|Xc|d|X');
402401
});
403402

403+
describe('nested watching', () {
404+
it('should not error when the first watched item is removed', () {
405+
element = compile(
406+
'<ul>'
407+
' <li ng-repeat="i in items">'
408+
r' <input ng-model="items[$index]">'
409+
' </li>'
410+
'</ul>');
411+
scope.context['items'] = ['misko', 'shyam', 'frodo'];
412+
scope.apply();
413+
expect(element.children.length).toEqual(3);
414+
scope.context['items'].remove('misko');
415+
scope.apply();
416+
expect(element.children.length).toEqual(2);
417+
});
418+
419+
it('should not error when the last watched item is removed', () {
420+
element = compile(
421+
'<ul>'
422+
' <li ng-repeat="i in items">'
423+
r' <input ng-model="items[$index]">'
424+
' </li>'
425+
'</ul>');
426+
scope.context['items'] = ['misko', 'shyam', 'frodo'];
427+
scope.apply();
428+
expect(element.children.length).toEqual(3);
429+
scope.context['items'].remove('frodo');
430+
scope.apply();
431+
expect(element.children.length).toEqual(2);
432+
});
433+
434+
it('should not error when multiple watched items are removed at the same time', () {
435+
element = compile(
436+
'<ul>'
437+
' <li ng-repeat="i in items">'
438+
r' <input ng-model="items[$index]">'
439+
' </li>'
440+
'</ul>');
441+
scope.context['items'] = ['misko', 'shyam', 'frodo', 'igor'];
442+
scope.apply();
443+
expect(element.children.length).toEqual(4);
444+
scope.context['items'].remove('shyam');
445+
scope.context['items'].remove('frodo');
446+
scope.apply();
447+
expect(element.children.length).toEqual(2);
448+
});
449+
});
404450

405451
describe('stability', () {
406452
var a, b, c, d, lis;
@@ -420,7 +466,6 @@ main() {
420466
lis = element.querySelectorAll('li');
421467
});
422468

423-
424469
it(r'should preserve the order of elements', () {
425470
scope.context['items'] = [a, c, d];
426471
scope.apply();

0 commit comments

Comments
 (0)