fix(change detection): preserve memoized results from pure functions
This commit is contained in:
parent
b0e2ebda70
commit
5beaf6d735
|
@ -291,7 +291,7 @@ export class ChangeDetectorJITGenerator {
|
|||
|
||||
if (r.isPureFunction()) {
|
||||
var condition = r.args.map((a) => this._changeNames[a]).join(" || ");
|
||||
return `if (${condition}) { ${check} }`;
|
||||
return `if (${condition}) { ${check} } else { ${newValue} = ${oldValue}; }`;
|
||||
} else {
|
||||
return check;
|
||||
}
|
||||
|
|
|
@ -69,12 +69,11 @@ var _rootBindings = [bind(Reflector).toValue(reflector), TestabilityRegistry];
|
|||
|
||||
function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
|
||||
var bestChangeDetection: Type = DynamicChangeDetection;
|
||||
// Re-enable once all e2e tests pass
|
||||
// if (PreGeneratedChangeDetection.isSupported()) {
|
||||
// bestChangeDetection = PreGeneratedChangeDetection;
|
||||
//} else if (JitChangeDetection.isSupported()) {
|
||||
// bestChangeDetection = JitChangeDetection;
|
||||
//}
|
||||
if (PreGeneratedChangeDetection.isSupported()) {
|
||||
bestChangeDetection = PreGeneratedChangeDetection;
|
||||
} else if (JitChangeDetection.isSupported()) {
|
||||
bestChangeDetection = JitChangeDetection;
|
||||
}
|
||||
return [
|
||||
bind(DOCUMENT_TOKEN)
|
||||
.toValue(DOM.defaultDoc()),
|
||||
|
|
|
@ -352,7 +352,7 @@ class _CodegenState {
|
|||
if (r.isPureFunction()) {
|
||||
// Add an "if changed guard"
|
||||
var condition = r.args.map((a) => _changeNames[a]).join(' || ');
|
||||
return 'if ($condition) { $check }';
|
||||
return 'if ($condition) { $check } else { $newValue = $oldValue; }';
|
||||
} else {
|
||||
return check;
|
||||
}
|
||||
|
|
|
@ -303,5 +303,6 @@ var _availableDefinitions = [
|
|||
'address?.toString()',
|
||||
'sayHi("Jim")',
|
||||
'a()(99)',
|
||||
'a.sayHi("Jim")'
|
||||
'a.sayHi("Jim")',
|
||||
'passThrough([12])'
|
||||
];
|
||||
|
|
|
@ -54,8 +54,8 @@ const _DEFAULT_CONTEXT = CONST_EXPR(new Object());
|
|||
/**
|
||||
* Tests in this spec run against three different implementations of `AbstractChangeDetector`,
|
||||
* `dynamic` (which use reflection to inspect objects), `JIT` (which are generated only for
|
||||
* Javascript at runtime using `eval` to avoid the need for reflection) and `Pregen` (which are
|
||||
* generated only for Dart prior to app deploy to avoid the need for reflection).
|
||||
* Javascript at runtime using `eval`) and `Pregen` (which are generated only for Dart prior
|
||||
* to app deploy to avoid the need for reflection).
|
||||
*
|
||||
* Pre-generated classes require knowledge of the shape of the change detector at the time of Dart
|
||||
* transformation, so in these tests we abstract a `ChangeDetectorDefinition` out into the
|
||||
|
@ -304,6 +304,16 @@ export function main() {
|
|||
expect(val.dispatcher.log).toEqual(['propName=BvalueA']);
|
||||
});
|
||||
|
||||
describe('pure functions', () => {
|
||||
it('should preserve memoized result', () => {
|
||||
var person = new Person('bob');
|
||||
var val = _createChangeDetector('passThrough([12])', person);
|
||||
val.changeDetector.detectChanges();
|
||||
val.changeDetector.detectChanges();
|
||||
expect(val.dispatcher.loggedValues).toEqual([[12]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('change notification', () => {
|
||||
describe('simple checks', () => {
|
||||
it('should pass a change record to the dispatcher', () => {
|
||||
|
@ -948,6 +958,8 @@ class Person {
|
|||
|
||||
sayHi(m) { return `Hi, ${m}`; }
|
||||
|
||||
passThrough(val) { return val; }
|
||||
|
||||
toString(): string {
|
||||
var address = this.address == null ? '' : ' address=' + this.address.toString();
|
||||
|
||||
|
|
Loading…
Reference in New Issue