diff --git a/angular/src/directives/control-value-accessors/boolean-value-accessor.ts b/angular/src/directives/control-value-accessors/boolean-value-accessor.ts index 992646fdba..74d1d5066a 100644 --- a/angular/src/directives/control-value-accessors/boolean-value-accessor.ts +++ b/angular/src/directives/control-value-accessors/boolean-value-accessor.ts @@ -25,8 +25,8 @@ export class BooleanValueAccessor extends ValueAccessor { setIonicClasses(this.el); } - @HostListener('ionChange', ['$event.target.checked']) - _handleIonChange(value: any) { - this.handleChangeEvent(value); + @HostListener('ionChange', ['$event.target']) + _handleIonChange(el: any) { + this.handleChangeEvent(el, el.checked); } } diff --git a/angular/src/directives/control-value-accessors/numeric-value-accesssor.ts b/angular/src/directives/control-value-accessors/numeric-value-accesssor.ts index 11ae5fe1a4..7f667eb73a 100644 --- a/angular/src/directives/control-value-accessors/numeric-value-accesssor.ts +++ b/angular/src/directives/control-value-accessors/numeric-value-accesssor.ts @@ -20,9 +20,9 @@ export class NumericValueAccessor extends ValueAccessor { super(el); } - @HostListener('ionChange', ['$event.target.value']) - _handleIonChange(value: any) { - this.handleChangeEvent(value); + @HostListener('ionChange', ['$event.target']) + _handleIonChange(el: any) { + this.handleChangeEvent(el, el.value); } registerOnChange(fn: (_: number | null) => void) { diff --git a/angular/src/directives/control-value-accessors/radio-value-accessor.ts b/angular/src/directives/control-value-accessors/radio-value-accessor.ts index 324c78db66..ae68034ba3 100644 --- a/angular/src/directives/control-value-accessors/radio-value-accessor.ts +++ b/angular/src/directives/control-value-accessors/radio-value-accessor.ts @@ -20,8 +20,8 @@ export class RadioValueAccessor extends ValueAccessor { super(el); } - @HostListener('ionSelect', ['$event.target.checked']) - _handleIonSelect(value: any) { - this.handleChangeEvent(value); + @HostListener('ionSelect', ['$event.target']) + _handleIonSelect(el: any) { + this.handleChangeEvent(el, el.checked); } } diff --git a/angular/src/directives/control-value-accessors/select-value-accessor.ts b/angular/src/directives/control-value-accessors/select-value-accessor.ts index 6d9743f5e7..fddc164485 100644 --- a/angular/src/directives/control-value-accessors/select-value-accessor.ts +++ b/angular/src/directives/control-value-accessors/select-value-accessor.ts @@ -20,8 +20,8 @@ export class SelectValueAccessor extends ValueAccessor { super(el); } - @HostListener('ionChange', ['$event.target.value']) - _handleChangeEvent(value: any) { - this.handleChangeEvent(value); + @HostListener('ionChange', ['$event.target']) + _handleChangeEvent(el: any) { + this.handleChangeEvent(el, el.value); } } diff --git a/angular/src/directives/control-value-accessors/text-value-accessor.ts b/angular/src/directives/control-value-accessors/text-value-accessor.ts index 353a6fd438..7981a60510 100644 --- a/angular/src/directives/control-value-accessors/text-value-accessor.ts +++ b/angular/src/directives/control-value-accessors/text-value-accessor.ts @@ -20,8 +20,8 @@ export class TextValueAccessor extends ValueAccessor { super(el); } - @HostListener('ionChange', ['$event.target.value']) - _handleInputEvent(value: any) { - this.handleChangeEvent(value); + @HostListener('ionChange', ['$event.target']) + _handleInputEvent(el: any) { + this.handleChangeEvent(el, el.value); } } diff --git a/angular/src/directives/control-value-accessors/value-accessor.ts b/angular/src/directives/control-value-accessors/value-accessor.ts index acad8a790e..527d57bf03 100644 --- a/angular/src/directives/control-value-accessors/value-accessor.ts +++ b/angular/src/directives/control-value-accessors/value-accessor.ts @@ -16,18 +16,22 @@ export class ValueAccessor implements ControlValueAccessor { setIonicClasses(this.el); } - handleChangeEvent(value: any) { - if (value !== this.lastValue) { - this.lastValue = value; - this.onChange(value); + handleChangeEvent(el: HTMLElement, value: any) { + if (el === this.el.nativeElement) { + if (value !== this.lastValue) { + this.lastValue = value; + this.onChange(value); + } + setIonicClasses(this.el); } - setIonicClasses(this.el); } - @HostListener('ionBlur') - _handleBlurEvent() { - this.onTouched(); - setIonicClasses(this.el); + @HostListener('ionBlur', ['$event.target']) + _handleBlurEvent(el: any) { + if (el === this.el.nativeElement) { + this.onTouched(); + setIonicClasses(this.el); + } } registerOnChange(fn: (value: any) => void) { diff --git a/angular/test/test-app/e2e/src/inputs.e2e-spec.ts b/angular/test/test-app/e2e/src/inputs.e2e-spec.ts index bcc01d9e5c..38d070bf19 100644 --- a/angular/test/test-app/e2e/src/inputs.e2e-spec.ts +++ b/angular/test/test-app/e2e/src/inputs.e2e-spec.ts @@ -60,4 +60,10 @@ describe('inputs', () => { expect(await element(by.css('#select-note')).getText()).toEqual('playstation'); expect(await element(by.css('#range-note')).getText()).toEqual('20'); }); + + it('nested components should not interfere with NgModel', async () => { + expect(await element(by.css('#range-note')).getText()).toEqual('10'); + await element(by.css('#nested-toggle')).click(); + expect(await element(by.css('#range-note')).getText()).toEqual('10'); + }); }); diff --git a/angular/test/test-app/src/app/inputs/inputs.component.html b/angular/test/test-app/src/app/inputs/inputs.component.html index 1d9da7bc23..5e6ff4a9c4 100644 --- a/angular/test/test-app/src/app/inputs/inputs.component.html +++ b/angular/test/test-app/src/app/inputs/inputs.component.html @@ -93,7 +93,9 @@ Range Mirror - + + + {{range}}