diff --git a/modules/@angular/common/test/directives/ng_style_spec.ts b/modules/@angular/common/test/directives/ng_style_spec.ts index 9127d92d68..78e2557524 100644 --- a/modules/@angular/common/test/directives/ng_style_spec.ts +++ b/modules/@angular/common/test/directives/ng_style_spec.ts @@ -66,6 +66,41 @@ export function main() { }); })); + // keyValueDiffer is sensitive to key order #9115 + it('should change styles specified in an object expression', + inject( + [TestComponentBuilder, AsyncTestCompleter], + (tcb: TestComponentBuilder, async: AsyncTestCompleter) => { + const template = `
`; + + tcb.overrideTemplate(TestComponent, template) + .createAsync(TestComponent) + .then((fixture) => { + fixture.debugElement.componentInstance.expr = { + // height, width order is important here + height: '10px', + width: '10px' + }; + + fixture.detectChanges(); + let el = fixture.debugElement.children[0].nativeElement; + expect(getDOM().getStyle(el, 'height')).toEqual('10px'); + expect(getDOM().getStyle(el, 'width')).toEqual('10px'); + + fixture.debugElement.componentInstance.expr = { + // width, height order is important here + width: '5px', + height: '5px', + }; + + fixture.detectChanges(); + expect(getDOM().getStyle(el, 'height')).toEqual('5px'); + expect(getDOM().getStyle(el, 'width')).toEqual('5px'); + + async.done(); + }); + })); + it('should remove styles when deleting a key in an object expression', inject( [TestComponentBuilder, AsyncTestCompleter], diff --git a/modules/@angular/core/src/change_detection/differs/default_keyvalue_differ.ts b/modules/@angular/core/src/change_detection/differs/default_keyvalue_differ.ts index fa5d90540c..5b422ee756 100644 --- a/modules/@angular/core/src/change_detection/differs/default_keyvalue_differ.ts +++ b/modules/@angular/core/src/change_detection/differs/default_keyvalue_differ.ts @@ -79,7 +79,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer { throw new BaseException(`Error trying to diff '${map}'`); } - return this.check(map) ? this : null + return this.check(map) ? this : null; } onDestroy() {} @@ -96,11 +96,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer { let newSeqRecord: any; if (oldSeqRecord && key === oldSeqRecord.key) { newSeqRecord = oldSeqRecord; - if (!looseIdentical(value, oldSeqRecord.currentValue)) { - oldSeqRecord.previousValue = oldSeqRecord.currentValue; - oldSeqRecord.currentValue = value; - this._addToChanges(oldSeqRecord); - } + this._maybeAddToChanges(newSeqRecord, value); } else { seqChanged = true; if (oldSeqRecord !== null) { @@ -109,6 +105,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer { } if (records.has(key)) { newSeqRecord = records.get(key); + this._maybeAddToChanges(newSeqRecord, value); } else { newSeqRecord = new KeyValueChangeRecord(key); records.set(key, newSeqRecord); @@ -179,6 +176,14 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer { } } + private _maybeAddToChanges(record: KeyValueChangeRecord, newValue: any): void { + if (!looseIdentical(newValue, record.currentValue)) { + record.previousValue = record.currentValue; + record.currentValue = newValue; + this._addToChanges(record); + } + } + /** @internal */ _isInRemovals(record: KeyValueChangeRecord) { return record === this._removalsHead || record._nextRemoved !== null || diff --git a/modules/@angular/core/test/change_detection/differs/default_keyvalue_differ_spec.ts b/modules/@angular/core/test/change_detection/differs/default_keyvalue_differ_spec.ts index 06e78c31af..5054d107fb 100644 --- a/modules/@angular/core/test/change_detection/differs/default_keyvalue_differ_spec.ts +++ b/modules/@angular/core/test/change_detection/differs/default_keyvalue_differ_spec.ts @@ -189,11 +189,8 @@ export function main() { }); it('should work regardless key order', () => { - let m: {[k: string]: number} = {a: 0, b: 0}; - differ.check(m); - - m = {b: 1, a: 1}; - differ.check(m); + differ.check({a: 0, b: 0}); + differ.check({b: 1, a: 1}); expect(differ.toString()).toEqual(kvChangesAsString({ map: ['b[0->1]', 'a[0->1]'],