1
1
import {
2
2
AfterContentInit ,
3
+ ChangeDetectionStrategy ,
4
+ ChangeDetectorRef ,
3
5
Component ,
4
6
ContentChildren ,
5
7
Directive ,
@@ -126,14 +128,31 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
126
128
}
127
129
128
130
/** Whether the labels should appear after or before the radio-buttons. Defaults to 'after' */
129
- @Input ( ) labelPosition : 'before' | 'after' = 'after' ;
131
+ _labelPosition : 'before' | 'after' = 'after' ;
132
+ @Input ( )
133
+ get labelPosition ( ) : 'before' | 'after' {
134
+ return this . _labelPosition ;
135
+ }
136
+ set labelPosition ( v : 'before' | 'after' ) {
137
+ this . _labelPosition = v
138
+ if ( this . _radios ) {
139
+ this . _radios . forEach ( ( radio ) => {
140
+ radio . labelPosition = this . _labelPosition ;
141
+ } ) ;
142
+ }
143
+ }
130
144
131
145
/** Whether the radio button is disabled. */
132
146
@Input ( )
133
147
get disabled ( ) : boolean { return this . _disabled ; }
134
148
set disabled ( value ) {
135
149
// The presence of *any* disabled value makes the component disabled, *except* for false.
136
150
this . _disabled = ( value != null && value !== false ) ? true : null ;
151
+ if ( this . _radios ) {
152
+ this . _radios . forEach ( ( radio ) => {
153
+ radio . disabled = this . _disabled ;
154
+ } )
155
+ }
137
156
}
138
157
139
158
/** Value of the radio button. */
@@ -269,6 +288,7 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
269
288
'[class.mat-radio-disabled]' : 'disabled' ,
270
289
'[attr.id]' : 'id' ,
271
290
}
291
+ changeDetection : ChangeDetectionStrategy . OnPush ,
272
292
} )
273
293
export class MdRadioButton implements OnInit , AfterViewInit , OnDestroy {
274
294
@@ -279,15 +299,67 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy {
279
299
@Input ( ) name : string ;
280
300
281
301
/** Used to set the 'aria-label' attribute on the underlying input element. */
282
- @Input ( 'aria-label' ) ariaLabel : string ;
302
+ _ariaLabel : string ;
303
+ @Input ( 'aria-label' )
304
+ get ariaLabel ( ) : string {
305
+ return this . _ariaLabel ;
306
+ }
307
+ set ariaLabel ( value : string ) {
308
+ this . _ariaLabel = value ;
309
+ this . _change . markForCheck ( ) ;
310
+ }
283
311
284
312
/** The 'aria-labelledby' attribute takes precedence as the element's text alternative. */
285
- @Input ( 'aria-labelledby' ) ariaLabelledby : string ;
313
+ _ariaLabelledby : string ;
314
+ @Input ( 'aria-labelledby' )
315
+ get ariaLabelledby ( ) : string {
316
+ return this . _ariaLabelledby ;
317
+ }
318
+ set ariaLabelledby ( value : string ) {
319
+ this . _ariaLabelledby = value ;
320
+ this . _change . markForCheck ( ) ;
321
+ }
286
322
287
323
/** Whether the ripple effect for this radio button is disabled. */
288
324
@Input ( )
289
325
get disableRipple ( ) : boolean { return this . _disableRipple ; }
290
- set disableRipple ( value ) { this . _disableRipple = coerceBooleanProperty ( value ) ; }
326
+ set disableRipple ( value ) {
327
+ this . _disableRipple = coerceBooleanProperty ( value ) ;
328
+ this . _change . markForCheck ( ) ;
329
+ }
330
+
331
+ /**
332
+ * Event emitted when the checked state of this radio button changes.
333
+ * Change events are only emitted when the value changes due to user interaction with
334
+ * the radio button (the same behavior as `<input type-"radio">`).
335
+ */
336
+ @Output ( )
337
+ change : EventEmitter < MdRadioChange > = new EventEmitter < MdRadioChange > ( ) ;
338
+
339
+ /** The native `<input type=radio>` element */
340
+ @ViewChild ( 'input' ) _inputElement : ElementRef ;
341
+
342
+ constructor ( @Optional ( ) radioGroup : MdRadioGroup ,
343
+ private _elementRef : ElementRef ,
344
+ private _renderer : Renderer ,
345
+ private _change : ChangeDetectorRef ,
346
+ public radioDispatcher : UniqueSelectionDispatcher ) {
347
+ // Assertions. Ideally these should be stripped out by the compiler.
348
+ // TODO(jelbourn): Assert that there's no name binding AND a parent radio group.
349
+
350
+ this . radioGroup = radioGroup ;
351
+
352
+ radioDispatcher . listen ( ( id : string , name : string ) => {
353
+ if ( id != this . id && name == this . name ) {
354
+ this . checked = false ;
355
+ }
356
+ } ) ;
357
+ }
358
+
359
+ /** ID of the native input element inside `<md-radio-button>` */
360
+ get inputId ( ) : string {
361
+ return `${ this . id } -input` ;
362
+ }
291
363
292
364
/** Whether this radio button is checked. */
293
365
@Input ( )
@@ -311,6 +383,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy {
311
383
// Notify all radio buttons with the same name to un-check.
312
384
this . _radioDispatcher . notify ( this . id , this . name ) ;
313
385
}
386
+ this . _change . markForCheck ( ) ;
314
387
}
315
388
}
316
389
@@ -332,7 +405,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy {
332
405
this . radioGroup . selected = this ;
333
406
}
334
407
}
335
-
408
+ this . _change . markForCheck ( ) ;
336
409
}
337
410
}
338
411
@@ -349,6 +422,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy {
349
422
350
423
set align ( v ) {
351
424
this . labelPosition = ( v == 'start' ) ? 'after' : 'before' ;
425
+ this . _change . markForCheck ( ) ;
352
426
}
353
427
354
428
private _labelPosition : 'before' | 'after' ;
@@ -361,6 +435,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy {
361
435
362
436
set labelPosition ( value ) {
363
437
this . _labelPosition = value ;
438
+ this . _change . markForCheck ( ) ;
364
439
}
365
440
366
441
/** Whether the radio button is disabled. */
@@ -372,6 +447,7 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy {
372
447
set disabled ( value : boolean ) {
373
448
// The presence of *any* disabled value makes the component disabled, *except* for false.
374
449
this . _disabled = ( value != null && value !== false ) ? true : null ;
450
+ this . _change . markForCheck ( ) ;
375
451
}
376
452
377
453
/**
0 commit comments