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

Commit cd4e2e3

Browse files
committed
fix(change-detection): delay processing watch registration inside reaction fn.
If a reaction function registers a new watch that watch should not be processed until the next change detection cycle.
1 parent 3a92ac0 commit cd4e2e3

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

lib/change_detection/watch_group.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ class RootWatchGroup extends WatchGroup {
406406
int count = 0;
407407
if (processStopwatch != null) processStopwatch.stop();
408408
Watch dirtyWatch = _dirtyWatchHead;
409+
_dirtyWatchHead = _dirtyWatchTail = null;
409410
RootWatchGroup root = _rootGroup;
410411
root._removeCount = 0;
411412
while(dirtyWatch != null) {
@@ -421,7 +422,6 @@ class RootWatchGroup extends WatchGroup {
421422
dirtyWatch._nextDirtyWatch = null;
422423
dirtyWatch = nextDirtyWatch;
423424
}
424-
_dirtyWatchHead = _dirtyWatchTail = null;
425425
if (processStopwatch != null) processStopwatch..stop()..increment(count);
426426
return count;
427427
}

test/change_detection/watch_group_spec.dart

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ void main() {
390390

391391
// obj, arg0, arg1;
392392
expect(watchGrp.fieldCost).toEqual(3);
393-
// methodA(), mothodA()
393+
// methodA(), methodA()
394394
expect(watchGrp.evalCost).toEqual(2);
395395

396396
watchGrp.detectChanges();
@@ -423,6 +423,30 @@ void main() {
423423
expect(logger).toEqual([]);
424424
});
425425

426+
it('should not return null when evaling method first time', () {
427+
context['text'] ='abc';
428+
var ast = new MethodAST(parse('text'), 'toUpperCase', []);
429+
var watch = watchGrp.watch(ast, (v, p) => logger(v));
430+
431+
watchGrp.detectChanges();
432+
expect(logger).toEqual(['ABC']);
433+
});
434+
435+
it('should not eval a function if registered during reaction', () {
436+
context['text'] ='abc';
437+
var ast = new MethodAST(parse('text'), 'toLowerCase', []);
438+
var watch = watchGrp.watch(ast, (v, p) {
439+
var ast = new MethodAST(parse('text'), 'toUpperCase', []);
440+
watchGrp.watch(ast, (v, p) {
441+
logger(v);
442+
});
443+
});
444+
445+
watchGrp.detectChanges();
446+
watchGrp.detectChanges();
447+
expect(logger).toEqual(['ABC']);
448+
});
449+
426450
it('should read connstant', () {
427451
// should fire on initial adding
428452
expect(watchGrp.fieldCost).toEqual(0);

test/core/scope_spec.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,39 @@ void main() {
11891189
}));
11901190

11911191

1192+
it('should properly watch array of fields', inject((RootScope rootScope, Logger log) {
1193+
rootScope.context['foo'] = () => 12;
1194+
rootScope.watch('foo()', (v, o) => log(v));
1195+
expect(log).toEqual([]);
1196+
rootScope.apply();
1197+
expect(log).toEqual([12]);
1198+
}));
1199+
1200+
1201+
it('should properly watch array of fields', inject((RootScope rootScope, Logger log) {
1202+
rootScope.context['foo'] = 'abc';
1203+
rootScope.watch('foo.contains("b")', (v, o) => log([v, o]));
1204+
expect(log).toEqual([]);
1205+
rootScope.apply();
1206+
expect(log).toEqual([[true, null]]);
1207+
log.clear();
1208+
}));
1209+
1210+
1211+
it('should not trigger new watcher in the flush where it was added', inject((Scope scope) {
1212+
var log = [] ;
1213+
scope.context['foo'] = () => 'foo';
1214+
scope.watch('1', (value, __) {
1215+
expect(value).toEqual(1);
1216+
scope.watch('foo()', (value, __) {
1217+
log.add(value);
1218+
});
1219+
});
1220+
scope.apply();
1221+
expect(log).toEqual(['foo']);
1222+
}));
1223+
1224+
11921225
it('should properly watch array of fields2', inject((RootScope rootScope, Logger log) {
11931226
rootScope.watch('[ctrl.foo, ctrl.bar]', (v, o) => log([v, o]));
11941227
expect(log).toEqual([]);

0 commit comments

Comments
 (0)