@@ -12,6 +12,7 @@ import {
1212 Component ,
1313 ElementRef ,
1414 forwardRef ,
15+ Inject ,
1516 Input ,
1617 NgZone ,
1718 OnDestroy ,
@@ -88,7 +89,7 @@ export class NzRadioComponent implements ControlValueAccessor, AfterViewInit, On
8889 isRadioButton = ! ! this . nzRadioButtonDirective ;
8990 onChange : OnChangeType = ( ) => { } ;
9091 onTouched : OnTouchedType = ( ) => { } ;
91- @ViewChild ( 'inputElement' , { static : false } ) inputElement ? : ElementRef ;
92+ @ViewChild ( 'inputElement' , { static : true } ) inputElement ! : ElementRef < HTMLInputElement > ;
9293 @Input ( ) nzValue : NzSafeAny | null = null ;
9394 @Input ( ) @InputBoolean ( ) nzDisabled = false ;
9495 @Input ( ) @InputBoolean ( ) nzAutoFocus = false ;
@@ -109,8 +110,8 @@ export class NzRadioComponent implements ControlValueAccessor, AfterViewInit, On
109110 private cdr : ChangeDetectorRef ,
110111 private focusMonitor : FocusMonitor ,
111112 @Optional ( ) private directionality : Directionality ,
112- @Optional ( ) private nzRadioService : NzRadioService ,
113- @Optional ( ) private nzRadioButtonDirective : NzRadioButtonDirective
113+ @Optional ( ) @ Inject ( NzRadioService ) private nzRadioService : NzRadioService | null ,
114+ @Optional ( ) @ Inject ( NzRadioButtonDirective ) private nzRadioButtonDirective : NzRadioButtonDirective | null
114115 ) { }
115116
116117 setDisabledState ( disabled : boolean ) : void {
@@ -143,7 +144,21 @@ export class NzRadioComponent implements ControlValueAccessor, AfterViewInit, On
143144 this . cdr . markForCheck ( ) ;
144145 } ) ;
145146 this . nzRadioService . selected$ . pipe ( takeUntil ( this . destroy$ ) ) . subscribe ( value => {
147+ const isChecked = this . isChecked ;
146148 this . isChecked = this . nzValue === value ;
149+ // We don't have to run `onChange()` on each `nz-radio` button whenever the `selected$` emits.
150+ // If we have 8 `nz-radio` buttons within the `nz-radio-group` and they're all connected with
151+ // `ngModel` or `formControl` then `onChange()` will be called 8 times for each `nz-radio` button.
152+ // We prevent this by checking if `isChecked` has been changed or not.
153+ if (
154+ this . isNgModel &&
155+ isChecked !== this . isChecked &&
156+ // We're only intereted if `isChecked` has been changed to `false` value to emit `false` to the ascendant form,
157+ // since we already emit `true` within the `setupClickListener`.
158+ this . isChecked === false
159+ ) {
160+ this . onChange ( false ) ;
161+ }
147162 this . cdr . markForCheck ( ) ;
148163 } ) ;
149164 }
@@ -193,9 +208,7 @@ export class NzRadioComponent implements ControlValueAccessor, AfterViewInit, On
193208 return ;
194209 }
195210 this . ngZone . run ( ( ) => {
196- if ( this . nzRadioService ) {
197- this . nzRadioService . select ( this . nzValue ) ;
198- }
211+ this . nzRadioService ?. select ( this . nzValue ) ;
199212 if ( this . isNgModel ) {
200213 this . isChecked = true ;
201214 this . onChange ( true ) ;
0 commit comments