From e73ad6be771d2f3900fcf2ade0ba7afcd4de0e81 Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Wed, 4 Jan 2017 12:15:20 -0800 Subject: [PATCH 1/9] Make MdRadioButton OnPush --- src/lib/radio/radio.ts | 80 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 5 deletions(-) diff --git a/src/lib/radio/radio.ts b/src/lib/radio/radio.ts index 803380aeed5e..172cf856e678 100644 --- a/src/lib/radio/radio.ts +++ b/src/lib/radio/radio.ts @@ -1,5 +1,7 @@ import { AfterContentInit, + ChangeDetectionStrategy, + ChangeDetectorRef, Component, ContentChildren, Directive, @@ -130,7 +132,19 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase } /** Whether the labels should appear after or before the radio-buttons. Defaults to 'after' */ - @Input() labelPosition: 'before' | 'after' = 'after'; + _labelPosition: 'before' | 'after' = 'after'; + @Input() + get labelPosition(): 'before' | 'after' { + return this._labelPosition; + } + set labelPosition(v: 'before' | 'after') { + this._labelPosition = v + if (this._radios) { + this._radios.forEach((radio) => { + radio.labelPosition = this._labelPosition; + }); + } + } /** Value of the radio button. */ @Input() @@ -265,6 +279,7 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase '[class.mat-radio-disabled]': 'disabled', '[attr.id]': 'id', } + changeDetection: ChangeDetectionStrategy.OnPush, }) export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { @@ -275,15 +290,67 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { @Input() name: string; /** Used to set the 'aria-label' attribute on the underlying input element. */ - @Input('aria-label') ariaLabel: string; + _ariaLabel: string; + @Input('aria-label') + get ariaLabel(): string { + return this._ariaLabel; + } + set ariaLabel(value: string) { + this._ariaLabel = value; + this._change.markForCheck(); + } /** The 'aria-labelledby' attribute takes precedence as the element's text alternative. */ - @Input('aria-labelledby') ariaLabelledby: string; + _ariaLabelledby: string; + @Input('aria-labelledby') + get ariaLabelledby(): string { + return this._ariaLabelledby; + } + set ariaLabelledby(value: string) { + this._ariaLabelledby = value; + this._change.markForCheck(); + } /** Whether the ripple effect for this radio button is disabled. */ @Input() get disableRipple(): boolean { return this._disableRipple; } - set disableRipple(value) { this._disableRipple = coerceBooleanProperty(value); } + set disableRipple(value) { + this._disableRipple = coerceBooleanProperty(value); + this._change.markForCheck(); + } + + /** + * Event emitted when the checked state of this radio button changes. + * Change events are only emitted when the value changes due to user interaction with + * the radio button (the same behavior as ``). + */ + @Output() + change: EventEmitter = new EventEmitter(); + + /** The native `` element */ + @ViewChild('input') _inputElement: ElementRef; + + constructor(@Optional() radioGroup: MdRadioGroup, + private _elementRef: ElementRef, + private _renderer: Renderer, + private _change: ChangeDetectorRef, + public radioDispatcher: UniqueSelectionDispatcher) { + // Assertions. Ideally these should be stripped out by the compiler. + // TODO(jelbourn): Assert that there's no name binding AND a parent radio group. + + this.radioGroup = radioGroup; + + radioDispatcher.listen((id: string, name: string) => { + if (id != this.id && name == this.name) { + this.checked = false; + } + }); + } + + /** ID of the native input element inside `` */ + get inputId(): string { + return `${this.id}-input`; + } /** Whether this radio button is checked. */ @Input() @@ -307,6 +374,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { // Notify all radio buttons with the same name to un-check. this._radioDispatcher.notify(this.id, this.name); } + this._change.markForCheck(); } } @@ -328,7 +396,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { this.radioGroup.selected = this; } } - + this._change.markForCheck(); } } @@ -345,6 +413,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { set align(v) { this.labelPosition = (v == 'start') ? 'after' : 'before'; + this._change.markForCheck(); } private _labelPosition: 'before' | 'after'; @@ -357,6 +426,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { set labelPosition(value) { this._labelPosition = value; + this._change.markForCheck(); } /** Whether the radio button is disabled. */ From 44ef4c0c6464544e3e913585fb5a315a5a128193 Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Wed, 11 Jan 2017 15:23:13 -0800 Subject: [PATCH 2/9] . --- src/lib/radio/radio.ts | 47 +++++++----------------------------------- 1 file changed, 7 insertions(+), 40 deletions(-) diff --git a/src/lib/radio/radio.ts b/src/lib/radio/radio.ts index 172cf856e678..afc4aa1ba5a2 100644 --- a/src/lib/radio/radio.ts +++ b/src/lib/radio/radio.ts @@ -132,19 +132,7 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase } /** Whether the labels should appear after or before the radio-buttons. Defaults to 'after' */ - _labelPosition: 'before' | 'after' = 'after'; - @Input() - get labelPosition(): 'before' | 'after' { - return this._labelPosition; - } - set labelPosition(v: 'before' | 'after') { - this._labelPosition = v - if (this._radios) { - this._radios.forEach((radio) => { - radio.labelPosition = this._labelPosition; - }); - } - } + @Input() labelPosition: 'before' | 'after' = 'after'; /** Value of the radio button. */ @Input() @@ -174,6 +162,8 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase this._checkSelectedRadioButton(); } + constructor(private _change: ChangeDetectorRef) {} + /** * Initialize properties once content children are available. * This allows us to propagate relevant attributes to associated buttons. @@ -235,6 +225,7 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase */ writeValue(value: any) { this.value = value; + this._change.markForCheck(); } /** @@ -290,34 +281,15 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { @Input() name: string; /** Used to set the 'aria-label' attribute on the underlying input element. */ - _ariaLabel: string; - @Input('aria-label') - get ariaLabel(): string { - return this._ariaLabel; - } - set ariaLabel(value: string) { - this._ariaLabel = value; - this._change.markForCheck(); - } + @Input('aria-label') ariaLabel: string; /** The 'aria-labelledby' attribute takes precedence as the element's text alternative. */ - _ariaLabelledby: string; - @Input('aria-labelledby') - get ariaLabelledby(): string { - return this._ariaLabelledby; - } - set ariaLabelledby(value: string) { - this._ariaLabelledby = value; - this._change.markForCheck(); - } + @Input('aria-labelledby') ariaLabelledby: string; /** Whether the ripple effect for this radio button is disabled. */ @Input() get disableRipple(): boolean { return this._disableRipple; } - set disableRipple(value) { - this._disableRipple = coerceBooleanProperty(value); - this._change.markForCheck(); - } + set disableRipple(value) { this._disableRipple = coerceBooleanProperty(value); } /** * Event emitted when the checked state of this radio button changes. @@ -333,7 +305,6 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { constructor(@Optional() radioGroup: MdRadioGroup, private _elementRef: ElementRef, private _renderer: Renderer, - private _change: ChangeDetectorRef, public radioDispatcher: UniqueSelectionDispatcher) { // Assertions. Ideally these should be stripped out by the compiler. // TODO(jelbourn): Assert that there's no name binding AND a parent radio group. @@ -374,7 +345,6 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { // Notify all radio buttons with the same name to un-check. this._radioDispatcher.notify(this.id, this.name); } - this._change.markForCheck(); } } @@ -396,7 +366,6 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { this.radioGroup.selected = this; } } - this._change.markForCheck(); } } @@ -413,7 +382,6 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { set align(v) { this.labelPosition = (v == 'start') ? 'after' : 'before'; - this._change.markForCheck(); } private _labelPosition: 'before' | 'after'; @@ -426,7 +394,6 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { set labelPosition(value) { this._labelPosition = value; - this._change.markForCheck(); } /** Whether the radio button is disabled. */ From 7026609892670fbabea5c01329b1a4617976289f Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Tue, 17 Jan 2017 17:23:53 -0800 Subject: [PATCH 3/9] Fixed tests --- src/lib/radio/radio.spec.ts | 13 +++++++++---- src/lib/radio/radio.ts | 22 +++++++++++++++++++++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/lib/radio/radio.spec.ts b/src/lib/radio/radio.spec.ts index 5f2c67c86e2b..c627be6a18d0 100644 --- a/src/lib/radio/radio.spec.ts +++ b/src/lib/radio/radio.spec.ts @@ -417,11 +417,13 @@ describe('MdRadio', () => { it('should write to the radio button based on ngModel', fakeAsync(() => { testComponent.modelValue = 'chocolate'; + fixture.detectChanges(); tick(); fixture.detectChanges(); expect(innerRadios[1].nativeElement.checked).toBe(true); + expect(radioInstances[1].checked).toBe(true); })); it('should update the ngModel value when selecting a radio button', () => { @@ -551,7 +553,7 @@ describe('MdRadio', () => { it('should change aria-label attribute if property is changed at runtime', () => { expect(fruitRadioNativeInputs[0].getAttribute('aria-label')).toBe('Banana'); - fruitRadioInstances[0].ariaLabel = 'Pineapple'; + testComponent.ariaLabel = 'Pineapple'; fixture.detectChanges(); expect(fruitRadioNativeInputs[0].getAttribute('aria-label')).toBe('Pineapple'); @@ -568,7 +570,7 @@ describe('MdRadio', () => { it('should change aria-labelledby attribute if property is changed at runtime', () => { expect(fruitRadioNativeInputs[0].getAttribute('aria-labelledby')).toBe('xyz'); - fruitRadioInstances[0].ariaLabelledby = 'uvw'; + testComponent.ariaLabelledby = 'uvw'; fixture.detectChanges(); expect(fruitRadioNativeInputs[0].getAttribute('aria-labelledby')).toBe('uvw'); @@ -618,12 +620,15 @@ class RadiosInsideRadioGroup { Autumn Baby Banana - + Raspberry ` }) -class StandaloneRadioButtons { } +class StandaloneRadioButtons { + ariaLabel: string = 'Banana'; + ariaLabelledby: string = 'xyz'; +} @Component({ diff --git a/src/lib/radio/radio.ts b/src/lib/radio/radio.ts index afc4aa1ba5a2..27ebeb68e9de 100644 --- a/src/lib/radio/radio.ts +++ b/src/lib/radio/radio.ts @@ -88,6 +88,9 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase /** Whether the `value` has been set to its initial value. */ private _isInitialized: boolean = false; + /** Whether the labels should appear after or before the radio-buttons. Defaults to 'after' */ + private _labelPosition: 'before' | 'after' = 'after'; + /** The method to be called in order to update ngModel */ _controlValueAccessorChangeFn: (value: any) => void = (value) => {}; @@ -131,8 +134,19 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase this.labelPosition = (v == 'start') ? 'after' : 'before'; } + /** Whether the labels should appear after or before the radio-buttons. Defaults to 'after' */ - @Input() labelPosition: 'before' | 'after' = 'after'; + @Input() + get labelPosition() { + return this._labelPosition; + } + + set labelPosition(v) { + this._labelPosition = (v == 'before') ? 'before' : 'after'; + if (this._radios) { + this._radios.forEach(radio => radio.groupValueChanged()); + } + } /** Value of the radio button. */ @Input() @@ -305,6 +319,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { constructor(@Optional() radioGroup: MdRadioGroup, private _elementRef: ElementRef, private _renderer: Renderer, + private _changeDetector: ChangeDetectorRef, public radioDispatcher: UniqueSelectionDispatcher) { // Assertions. Ideally these should be stripped out by the compiler. // TODO(jelbourn): Assert that there's no name binding AND a parent radio group. @@ -345,6 +360,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { // Notify all radio buttons with the same name to un-check. this._radioDispatcher.notify(this.id, this.name); } + this._changeDetector.markForCheck(); } } @@ -464,6 +480,10 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { this._focusOriginMonitor.focusVia(this._inputElement.nativeElement, this._renderer, 'keyboard'); } + groupValueChanged() { + this._changeDetector.markForCheck(); + } + ngOnInit() { if (this.radioGroup) { // If the radio is inside a radio group, determine if it should be checked From 6691443c2427bd0023798cde26de9a7c077e2d7a Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Tue, 17 Jan 2017 17:39:15 -0800 Subject: [PATCH 4/9] fixed group ripple disabled test --- src/lib/radio/radio.spec.ts | 4 +++- src/lib/radio/radio.ts | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/radio/radio.spec.ts b/src/lib/radio/radio.spec.ts index c627be6a18d0..3721ff221be1 100644 --- a/src/lib/radio/radio.spec.ts +++ b/src/lib/radio/radio.spec.ts @@ -595,7 +595,8 @@ describe('MdRadio', () => { [labelPosition]="labelPos" [value]="groupValue" name="test-name"> - Charmander + Charmander Squirtle Bulbasaur @@ -604,6 +605,7 @@ describe('MdRadio', () => { class RadiosInsideRadioGroup { labelPos: 'before' | 'after'; isGroupDisabled: boolean = false; + isFirstDisabled: boolean = false; groupValue: string = null; disableRipple: boolean = false; } diff --git a/src/lib/radio/radio.ts b/src/lib/radio/radio.ts index 27ebeb68e9de..569530557700 100644 --- a/src/lib/radio/radio.ts +++ b/src/lib/radio/radio.ts @@ -144,7 +144,7 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase set labelPosition(v) { this._labelPosition = (v == 'before') ? 'before' : 'after'; if (this._radios) { - this._radios.forEach(radio => radio.groupValueChanged()); + this._radios.forEach(radio => radio._groupValueChanged()); } } @@ -480,7 +480,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { this._focusOriginMonitor.focusVia(this._inputElement.nativeElement, this._renderer, 'keyboard'); } - groupValueChanged() { + _groupValueChanged() { this._changeDetector.markForCheck(); } From 7b0cfecea348a551b9f57b4ad4bc146be0eee7d6 Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Wed, 18 Jan 2017 10:49:34 -0800 Subject: [PATCH 5/9] fix lint --- src/lib/radio/radio.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib/radio/radio.spec.ts b/src/lib/radio/radio.spec.ts index 3721ff221be1..dc27008336e6 100644 --- a/src/lib/radio/radio.spec.ts +++ b/src/lib/radio/radio.spec.ts @@ -622,7 +622,10 @@ class RadiosInsideRadioGroup { Autumn Baby Banana - + Raspberry ` From 96fb7d7fc34af17f55073ddcdcc2ecba7169a3f5 Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Thu, 2 Mar 2017 14:49:32 -0800 Subject: [PATCH 6/9] fix test --- src/lib/radio/radio.ts | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/src/lib/radio/radio.ts b/src/lib/radio/radio.ts index 569530557700..e74536432ef3 100644 --- a/src/lib/radio/radio.ts +++ b/src/lib/radio/radio.ts @@ -283,7 +283,7 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase '[class.mat-radio-checked]': 'checked', '[class.mat-radio-disabled]': 'disabled', '[attr.id]': 'id', - } + }, changeDetection: ChangeDetectionStrategy.OnPush, }) export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { @@ -305,39 +305,6 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { get disableRipple(): boolean { return this._disableRipple; } set disableRipple(value) { this._disableRipple = coerceBooleanProperty(value); } - /** - * Event emitted when the checked state of this radio button changes. - * Change events are only emitted when the value changes due to user interaction with - * the radio button (the same behavior as ``). - */ - @Output() - change: EventEmitter = new EventEmitter(); - - /** The native `` element */ - @ViewChild('input') _inputElement: ElementRef; - - constructor(@Optional() radioGroup: MdRadioGroup, - private _elementRef: ElementRef, - private _renderer: Renderer, - private _changeDetector: ChangeDetectorRef, - public radioDispatcher: UniqueSelectionDispatcher) { - // Assertions. Ideally these should be stripped out by the compiler. - // TODO(jelbourn): Assert that there's no name binding AND a parent radio group. - - this.radioGroup = radioGroup; - - radioDispatcher.listen((id: string, name: string) => { - if (id != this.id && name == this.name) { - this.checked = false; - } - }); - } - - /** ID of the native input element inside `` */ - get inputId(): string { - return `${this.id}-input`; - } - /** Whether this radio button is checked. */ @Input() get checked(): boolean { From e1a36189594ed47dfec2a30cf15ca9ef6446da16 Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Mon, 1 May 2017 15:31:53 -0700 Subject: [PATCH 7/9] sync and fix test --- src/lib/radio/radio.ts | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/lib/radio/radio.ts b/src/lib/radio/radio.ts index e74536432ef3..0cc3768a04a6 100644 --- a/src/lib/radio/radio.ts +++ b/src/lib/radio/radio.ts @@ -91,6 +91,9 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase /** Whether the labels should appear after or before the radio-buttons. Defaults to 'after' */ private _labelPosition: 'before' | 'after' = 'after'; + /** Whether the radio group is disabled. */ + private _disabled: boolean = false; + /** The method to be called in order to update ngModel */ _controlValueAccessorChangeFn: (value: any) => void = (value) => {}; @@ -176,7 +179,20 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase this._checkSelectedRadioButton(); } - constructor(private _change: ChangeDetectorRef) {} + /** Whether the radio group is diabled */ + @Input() + get disabled() { return this._disabled; } + set disabled(value) { + this._disabled = value; + if (this._radios) { + // Update radios disabled state + this._radios.forEach((r) => r._groupValueChanged()); + } + } + + constructor(private _change: ChangeDetectorRef) { + super(); + } /** * Initialize properties once content children are available. @@ -266,6 +282,7 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase */ setDisabledState(isDisabled: boolean) { this.disabled = isDisabled; + this._change.markForCheck(); } } @@ -384,9 +401,10 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { get disabled(): boolean { return this._disabled || (this.radioGroup != null && this.radioGroup.disabled); } - set disabled(value: boolean) { this._disabled = coerceBooleanProperty(value); + // Update rippleDisabled + this._changeDetector.markForCheck(); } /** @@ -428,6 +446,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { constructor(@Optional() radioGroup: MdRadioGroup, private _elementRef: ElementRef, private _renderer: Renderer2, + private _changeDetector: ChangeDetectorRef, private _focusOriginMonitor: FocusOriginMonitor, private _radioDispatcher: UniqueSelectionDispatcher) { // Assertions. Ideally these should be stripped out by the compiler. @@ -448,6 +467,8 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { } _groupValueChanged() { + // When group value changes, the button will not be notified. Use `markForCheck` to explicit + // update radio button's status this._changeDetector.markForCheck(); } From 0e4dfdc6ced4d425a17841ae4ce5e4f3b7bf760c Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Tue, 23 May 2017 11:37:16 -0700 Subject: [PATCH 8/9] address comments --- src/lib/radio/radio.spec.ts | 4 ++-- src/lib/radio/radio.ts | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/lib/radio/radio.spec.ts b/src/lib/radio/radio.spec.ts index dc27008336e6..20dec0dddccb 100644 --- a/src/lib/radio/radio.spec.ts +++ b/src/lib/radio/radio.spec.ts @@ -229,7 +229,7 @@ describe('MdRadio', () => { }); it('should not show ripples on disabled radio buttons', () => { - radioInstances[0].disabled = true; + testComponent.isFirstDisabled = true; fixture.detectChanges(); dispatchFakeEvent(radioLabelElements[0], 'mousedown'); @@ -238,7 +238,7 @@ describe('MdRadio', () => { expect(radioNativeElements[0].querySelectorAll('.mat-ripple-element').length) .toBe(0, 'Expected a disabled radio button to not show ripples'); - radioInstances[0].disabled = false; + testComponent.isFirstDisabled = false; fixture.detectChanges(); dispatchFakeEvent(radioLabelElements[0], 'mousedown'); diff --git a/src/lib/radio/radio.ts b/src/lib/radio/radio.ts index 0cc3768a04a6..3507c23dae24 100644 --- a/src/lib/radio/radio.ts +++ b/src/lib/radio/radio.ts @@ -146,9 +146,7 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase set labelPosition(v) { this._labelPosition = (v == 'before') ? 'before' : 'after'; - if (this._radios) { - this._radios.forEach(radio => radio._groupValueChanged()); - } + this._markRadiosForCheck(); } /** Value of the radio button. */ @@ -186,7 +184,7 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase this._disabled = value; if (this._radios) { // Update radios disabled state - this._radios.forEach((r) => r._groupValueChanged()); + this._radios.forEach((r) => r._markForCheck()); } } @@ -249,6 +247,12 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase } } + _markRadiosForCheck() { + if (this._radios) { + this._radios.forEach(radio => radio._markForCheck()); + } + } + /** * Sets the model value. Implemented as part of ControlValueAccessor. * @param value @@ -403,8 +407,6 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { } set disabled(value: boolean) { this._disabled = coerceBooleanProperty(value); - // Update rippleDisabled - this._changeDetector.markForCheck(); } /** @@ -466,7 +468,12 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { this._focusOriginMonitor.focusVia(this._inputElement.nativeElement, this._renderer, 'keyboard'); } - _groupValueChanged() { + /** + * Marks the radio button as needing checking for change detection. + * This method is exposed because the parent radio group will directly + * update bound properties of the radio button. + */ + _markForCheck() { // When group value changes, the button will not be notified. Use `markForCheck` to explicit // update radio button's status this._changeDetector.markForCheck(); From f7ec78796abb13cccb1053bac297bb03d3da4969 Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Tue, 23 May 2017 11:50:02 -0700 Subject: [PATCH 9/9] address comments --- src/lib/radio/radio.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/lib/radio/radio.ts b/src/lib/radio/radio.ts index 3507c23dae24..bc099bec0996 100644 --- a/src/lib/radio/radio.ts +++ b/src/lib/radio/radio.ts @@ -182,13 +182,10 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase get disabled() { return this._disabled; } set disabled(value) { this._disabled = value; - if (this._radios) { - // Update radios disabled state - this._radios.forEach((r) => r._markForCheck()); - } + this._markRadiosForCheck(); } - constructor(private _change: ChangeDetectorRef) { + constructor(private _changeDetector: ChangeDetectorRef) { super(); } @@ -259,7 +256,7 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase */ writeValue(value: any) { this.value = value; - this._change.markForCheck(); + this._changeDetector.markForCheck(); } /** @@ -286,7 +283,7 @@ export class MdRadioGroup extends _MdRadioGroupMixinBase */ setDisabledState(isDisabled: boolean) { this.disabled = isDisabled; - this._change.markForCheck(); + this._changeDetector.markForCheck(); } }