Skip to content

Commit 5beaf6d

Browse files
committed
fix(change detection): preserve memoized results from pure functions
1 parent b0e2ebd commit 5beaf6d

File tree

5 files changed

+23
-11
lines changed

5 files changed

+23
-11
lines changed

modules/angular2/src/change_detection/change_detection_jit_generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ export class ChangeDetectorJITGenerator {
291291

292292
if (r.isPureFunction()) {
293293
var condition = r.args.map((a) => this._changeNames[a]).join(" || ");
294-
return `if (${condition}) { ${check} }`;
294+
return `if (${condition}) { ${check} } else { ${newValue} = ${oldValue}; }`;
295295
} else {
296296
return check;
297297
}

modules/angular2/src/core/application.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,11 @@ var _rootBindings = [bind(Reflector).toValue(reflector), TestabilityRegistry];
6969

7070
function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
7171
var bestChangeDetection: Type = DynamicChangeDetection;
72-
// Re-enable once all e2e tests pass
73-
// if (PreGeneratedChangeDetection.isSupported()) {
74-
// bestChangeDetection = PreGeneratedChangeDetection;
75-
//} else if (JitChangeDetection.isSupported()) {
76-
// bestChangeDetection = JitChangeDetection;
77-
//}
72+
if (PreGeneratedChangeDetection.isSupported()) {
73+
bestChangeDetection = PreGeneratedChangeDetection;
74+
} else if (JitChangeDetection.isSupported()) {
75+
bestChangeDetection = JitChangeDetection;
76+
}
7877
return [
7978
bind(DOCUMENT_TOKEN)
8079
.toValue(DOM.defaultDoc()),

modules/angular2/src/transform/template_compiler/change_detector_codegen.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ class _CodegenState {
352352
if (r.isPureFunction()) {
353353
// Add an "if changed guard"
354354
var condition = r.args.map((a) => _changeNames[a]).join(' || ');
355-
return 'if ($condition) { $check }';
355+
return 'if ($condition) { $check } else { $newValue = $oldValue; }';
356356
} else {
357357
return check;
358358
}

modules/angular2/test/change_detection/change_detector_config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,5 +303,6 @@ var _availableDefinitions = [
303303
'address?.toString()',
304304
'sayHi("Jim")',
305305
'a()(99)',
306-
'a.sayHi("Jim")'
306+
'a.sayHi("Jim")',
307+
'passThrough([12])'
307308
];

modules/angular2/test/change_detection/change_detector_spec.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ const _DEFAULT_CONTEXT = CONST_EXPR(new Object());
5454
/**
5555
* Tests in this spec run against three different implementations of `AbstractChangeDetector`,
5656
* `dynamic` (which use reflection to inspect objects), `JIT` (which are generated only for
57-
* Javascript at runtime using `eval` to avoid the need for reflection) and `Pregen` (which are
58-
* generated only for Dart prior to app deploy to avoid the need for reflection).
57+
* Javascript at runtime using `eval`) and `Pregen` (which are generated only for Dart prior
58+
* to app deploy to avoid the need for reflection).
5959
*
6060
* Pre-generated classes require knowledge of the shape of the change detector at the time of Dart
6161
* transformation, so in these tests we abstract a `ChangeDetectorDefinition` out into the
@@ -304,6 +304,16 @@ export function main() {
304304
expect(val.dispatcher.log).toEqual(['propName=BvalueA']);
305305
});
306306

307+
describe('pure functions', () => {
308+
it('should preserve memoized result', () => {
309+
var person = new Person('bob');
310+
var val = _createChangeDetector('passThrough([12])', person);
311+
val.changeDetector.detectChanges();
312+
val.changeDetector.detectChanges();
313+
expect(val.dispatcher.loggedValues).toEqual([[12]]);
314+
});
315+
});
316+
307317
describe('change notification', () => {
308318
describe('simple checks', () => {
309319
it('should pass a change record to the dispatcher', () => {
@@ -948,6 +958,8 @@ class Person {
948958

949959
sayHi(m) { return `Hi, ${m}`; }
950960

961+
passThrough(val) { return val; }
962+
951963
toString(): string {
952964
var address = this.address == null ? '' : ' address=' + this.address.toString();
953965

0 commit comments

Comments
 (0)