diff --git a/aio/tools/examples/run-example-e2e.js b/aio/tools/examples/run-example-e2e.js index ba6368401b..4049a2b1f3 100644 --- a/aio/tools/examples/run-example-e2e.js +++ b/aio/tools/examples/run-example-e2e.js @@ -21,9 +21,6 @@ const IGNORED_EXAMPLES = [ ]; const fixmeIvyExamples = [ - // fixmeIvy('unknown') version value goes undefined when clicking Major button after clicking - // Minor button twice - 'component-interaction', // fixmeIvy('unknown') failed content projection and applied styles 'component-styles', // fixmeIvy('unknown') ERROR Error: Unable to find context associated with [object diff --git a/packages/core/src/render3/features/ng_onchanges_feature.ts b/packages/core/src/render3/features/ng_onchanges_feature.ts index 21525e1157..660c12adf9 100644 --- a/packages/core/src/render3/features/ng_onchanges_feature.ts +++ b/packages/core/src/render3/features/ng_onchanges_feature.ts @@ -59,7 +59,16 @@ function wrapOnChanges() { const current = simpleChangesStore && simpleChangesStore.current; if (current) { - simpleChangesStore !.previous = current; + const previous = simpleChangesStore !.previous; + if (previous === EMPTY_OBJ) { + simpleChangesStore !.previous = current; + } else { + // New changes are copied to the previous store, so that we don't lose history for inputs + // which were not changed this time + for (let key in current) { + previous[key] = current[key]; + } + } simpleChangesStore !.current = null; this.ngOnChanges(current); } diff --git a/packages/core/test/acceptance/lifecycle_spec.ts b/packages/core/test/acceptance/lifecycle_spec.ts new file mode 100644 index 0000000000..3e32089dce --- /dev/null +++ b/packages/core/test/acceptance/lifecycle_spec.ts @@ -0,0 +1,59 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {Component, Input, OnChanges, SimpleChanges} from '@angular/core'; +import {TestBed} from '@angular/core/testing'; + +describe('ngOnChanges', () => { + it('should correctly support updating one Input among many', () => { + let log: string[] = []; + + @Component({selector: 'child-comp', template: 'child'}) + class ChildComp implements OnChanges { + @Input() a: number = 0; + @Input() b: number = 0; + @Input() c: number = 0; + + ngOnChanges(changes: SimpleChanges) { + for (let key in changes) { + const simpleChange = changes[key]; + log.push(key + ': ' + simpleChange.previousValue + ' -> ' + simpleChange.currentValue); + } + } + } + + @Component( + {selector: 'app-comp', template: ''}) + class AppComp { + a = 0; + b = 0; + c = 0; + } + + TestBed.configureTestingModule({declarations: [AppComp, ChildComp]}); + const fixture = TestBed.createComponent(AppComp); + fixture.detectChanges(); + const appComp = fixture.componentInstance; + expect(log).toEqual(['a: undefined -> 0', 'b: undefined -> 0', 'c: undefined -> 0']); + log.length = 0; + + appComp.a = 1; + fixture.detectChanges(); + expect(log).toEqual(['a: 0 -> 1']); + log.length = 0; + + appComp.b = 2; + fixture.detectChanges(); + expect(log).toEqual(['b: 0 -> 2']); + log.length = 0; + + appComp.c = 3; + fixture.detectChanges(); + expect(log).toEqual(['c: 0 -> 3']); + }); +}); \ No newline at end of file