From e5830d17ed2289d8d30450f1abd4fc1d159a0d69 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 2 Sep 2016 19:11:08 +0200 Subject: [PATCH] fix(button-toggle): toggle group should not emit an initial change event. (#1144) --- src/lib/button-toggle/button-toggle.spec.ts | 36 +++++++++++++++++++++ src/lib/button-toggle/button-toggle.ts | 20 ++++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/lib/button-toggle/button-toggle.spec.ts b/src/lib/button-toggle/button-toggle.spec.ts index 569745937955..ab93e493c71f 100644 --- a/src/lib/button-toggle/button-toggle.spec.ts +++ b/src/lib/button-toggle/button-toggle.spec.ts @@ -25,6 +25,7 @@ describe('MdButtonToggle', () => { ButtonTogglesInsideButtonToggleGroup, ButtonToggleGroupWithNgModel, ButtonTogglesInsideButtonToggleGroupMultiple, + ButtonToggleGroupWithInitialValue, StandaloneButtonToggle, ], }); @@ -320,6 +321,29 @@ describe('MdButtonToggle', () => { expect(testComponent.modelValue).toBe('red'); expect(testComponent.lastEvent.value).toBe('red'); })); + + }); + + describe('with initial value and change event', () => { + + it('should not fire an initial change event', async(() => { + let fixture = TestBed.createComponent(ButtonToggleGroupWithInitialValue); + let testComponent = fixture.debugElement.componentInstance; + let groupDebugElement = fixture.debugElement.query(By.directive(MdButtonToggleGroup)); + let groupInstance: MdButtonToggleGroup = groupDebugElement.injector.get(MdButtonToggleGroup); + + fixture.detectChanges(); + + expect(groupInstance.value).toBe('red'); + expect(testComponent.lastEvent).toBeFalsy(); + + groupInstance.value = 'green'; + fixture.detectChanges(); + + expect(groupInstance.value).toBe('green'); + expect(testComponent.lastEvent.value).toBe('green'); + })); + }); describe('inside of a multiple selection group', () => { @@ -532,3 +556,15 @@ class ButtonTogglesInsideButtonToggleGroupMultiple { ` }) class StandaloneButtonToggle { } + +@Component({ + template: ` + + Value Red + Value Green + + ` +}) +class ButtonToggleGroupWithInitialValue { + lastEvent: MdButtonToggleChange; +} diff --git a/src/lib/button-toggle/button-toggle.ts b/src/lib/button-toggle/button-toggle.ts index 0fdbf82368c8..918d48945c37 100644 --- a/src/lib/button-toggle/button-toggle.ts +++ b/src/lib/button-toggle/button-toggle.ts @@ -12,7 +12,8 @@ import { Output, QueryList, ViewEncapsulation, - forwardRef + forwardRef, + AfterViewInit } from '@angular/core'; import { NG_VALUE_ACCESSOR, @@ -52,7 +53,7 @@ export class MdButtonToggleChange { 'role': 'radiogroup', }, }) -export class MdButtonToggleGroup implements ControlValueAccessor { +export class MdButtonToggleGroup implements AfterViewInit, ControlValueAccessor { /** The value for the button toggle group. Should match currently selected button toggle. */ private _value: any = null; @@ -65,6 +66,9 @@ export class MdButtonToggleGroup implements ControlValueAccessor { /** The currently selected button toggle, should match the value. */ private _selected: MdButtonToggle = null; + /** Whether the button toggle group is initialized or not. */ + private _isInitialized: boolean = false; + /** The method to be called in order to update ngModel. */ private _controlValueAccessorChangeFn: (value: any) => void = (value) => {}; @@ -81,6 +85,11 @@ export class MdButtonToggleGroup implements ControlValueAccessor { @ContentChildren(forwardRef(() => MdButtonToggle)) _buttonToggles: QueryList = null; + /** TODO: internal */ + ngAfterViewInit() { + this._isInitialized = true; + } + @Input() get name(): string { return this._name; @@ -111,7 +120,12 @@ export class MdButtonToggleGroup implements ControlValueAccessor { this._value = newValue; this._updateSelectedButtonToggleFromValue(); - this._emitChangeEvent(); + + // Only emit a change event if the view is completely initialized. + // We don't want to emit a change event for the initial values. + if (this._isInitialized) { + this._emitChangeEvent(); + } } }