refactor(forms): add base class for all built-in ControlValueAccessors (#41225)

This commit adds a base class that contains common logic for all ControlValueAccessors defined in Forms package. This allows to remove duplicated logic from all built-in ControlValueAccessor classes.

PR Close #41225
This commit is contained in:
Andrew Kushnir 2021-03-15 18:56:06 -07:00 committed by Zach Arend
parent 44a7fae00f
commit 51bb922a08
11 changed files with 107 additions and 291 deletions

View File

@ -112,13 +112,7 @@ export declare interface AsyncValidatorFn {
(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>; (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
} }
export declare class CheckboxControlValueAccessor extends ɵangular_packages_forms_forms_f implements ControlValueAccessor { export declare class CheckboxControlValueAccessor extends ɵangular_packages_forms_forms_g implements ControlValueAccessor {
onChange: (_: any) => void;
onTouched: () => void;
constructor(_renderer: Renderer2, _elementRef: ElementRef);
registerOnChange(fn: (_: any) => {}): void;
registerOnTouched(fn: () => {}): void;
setDisabledState(isDisabled: boolean): void;
writeValue(value: any): void; writeValue(value: any): void;
} }
@ -141,13 +135,8 @@ export declare interface ControlValueAccessor {
writeValue(obj: any): void; writeValue(obj: any): void;
} }
export declare class DefaultValueAccessor implements ControlValueAccessor { export declare class DefaultValueAccessor extends ɵangular_packages_forms_forms_f implements ControlValueAccessor {
onChange: (_: any) => void; constructor(renderer: Renderer2, elementRef: ElementRef, _compositionMode: boolean);
onTouched: () => void;
constructor(_renderer: Renderer2, _elementRef: ElementRef, _compositionMode: boolean);
registerOnChange(fn: (_: any) => void): void;
registerOnTouched(fn: () => void): void;
setDisabledState(isDisabled: boolean): void;
writeValue(value: any): void; writeValue(value: any): void;
} }
@ -382,11 +371,11 @@ export declare abstract class NgControl extends AbstractControlDirective {
abstract viewToModelUpdate(newValue: any): void; abstract viewToModelUpdate(newValue: any): void;
} }
export declare class NgControlStatus extends ɵangular_packages_forms_forms_h { export declare class NgControlStatus extends ɵangular_packages_forms_forms_i {
constructor(cd: NgControl); constructor(cd: NgControl);
} }
export declare class NgControlStatusGroup extends ɵangular_packages_forms_forms_h { export declare class NgControlStatusGroup extends ɵangular_packages_forms_forms_i {
constructor(cd: ControlContainer); constructor(cd: ControlContainer);
} }
@ -454,13 +443,8 @@ export declare class NgSelectOption implements OnDestroy {
ngOnDestroy(): void; ngOnDestroy(): void;
} }
export declare class NumberValueAccessor extends ɵangular_packages_forms_forms_f implements ControlValueAccessor { export declare class NumberValueAccessor extends ɵangular_packages_forms_forms_g implements ControlValueAccessor {
onChange: (_: any) => void;
onTouched: () => void;
constructor(_renderer: Renderer2, _elementRef: ElementRef);
registerOnChange(fn: (_: number | null) => void): void; registerOnChange(fn: (_: number | null) => void): void;
registerOnTouched(fn: () => void): void;
setDisabledState(isDisabled: boolean): void;
writeValue(value: number): void; writeValue(value: number): void;
} }
@ -471,29 +455,21 @@ export declare class PatternValidator implements Validator, OnChanges {
validate(control: AbstractControl): ValidationErrors | null; validate(control: AbstractControl): ValidationErrors | null;
} }
export declare class RadioControlValueAccessor extends ɵangular_packages_forms_forms_f implements ControlValueAccessor, OnDestroy, OnInit { export declare class RadioControlValueAccessor extends ɵangular_packages_forms_forms_g implements ControlValueAccessor, OnDestroy, OnInit {
formControlName: string; formControlName: string;
name: string; name: string;
onChange: () => void; onChange: () => void;
onTouched: () => void;
value: any; value: any;
constructor(_renderer: Renderer2, _elementRef: ElementRef, _registry: ɵangular_packages_forms_forms_p, _injector: Injector); constructor(renderer: Renderer2, elementRef: ElementRef, _registry: ɵangular_packages_forms_forms_q, _injector: Injector);
fireUncheck(value: any): void; fireUncheck(value: any): void;
ngOnDestroy(): void; ngOnDestroy(): void;
ngOnInit(): void; ngOnInit(): void;
registerOnChange(fn: (_: any) => {}): void; registerOnChange(fn: (_: any) => {}): void;
registerOnTouched(fn: () => {}): void;
setDisabledState(isDisabled: boolean): void;
writeValue(value: any): void; writeValue(value: any): void;
} }
export declare class RangeValueAccessor extends ɵangular_packages_forms_forms_f implements ControlValueAccessor { export declare class RangeValueAccessor extends ɵangular_packages_forms_forms_g implements ControlValueAccessor {
onChange: (_: any) => void;
onTouched: () => void;
constructor(_renderer: Renderer2, _elementRef: ElementRef);
registerOnChange(fn: (_: number | null) => void): void; registerOnChange(fn: (_: number | null) => void): void;
registerOnTouched(fn: () => void): void;
setDisabledState(isDisabled: boolean): void;
writeValue(value: any): void; writeValue(value: any): void;
} }
@ -509,27 +485,17 @@ export declare class RequiredValidator implements Validator {
validate(control: AbstractControl): ValidationErrors | null; validate(control: AbstractControl): ValidationErrors | null;
} }
export declare class SelectControlValueAccessor extends ɵangular_packages_forms_forms_f implements ControlValueAccessor { export declare class SelectControlValueAccessor extends ɵangular_packages_forms_forms_g implements ControlValueAccessor {
set compareWith(fn: (o1: any, o2: any) => boolean); set compareWith(fn: (o1: any, o2: any) => boolean);
onChange: (_: any) => void;
onTouched: () => void;
value: any; value: any;
constructor(_renderer: Renderer2, _elementRef: ElementRef);
registerOnChange(fn: (value: any) => any): void; registerOnChange(fn: (value: any) => any): void;
registerOnTouched(fn: () => any): void;
setDisabledState(isDisabled: boolean): void;
writeValue(value: any): void; writeValue(value: any): void;
} }
export declare class SelectMultipleControlValueAccessor extends ɵangular_packages_forms_forms_f implements ControlValueAccessor { export declare class SelectMultipleControlValueAccessor extends ɵangular_packages_forms_forms_g implements ControlValueAccessor {
set compareWith(fn: (o1: any, o2: any) => boolean); set compareWith(fn: (o1: any, o2: any) => boolean);
onChange: (_: any) => void;
onTouched: () => void;
value: any; value: any;
constructor(_renderer: Renderer2, _elementRef: ElementRef);
registerOnChange(fn: (value: any) => any): void; registerOnChange(fn: (value: any) => any): void;
registerOnTouched(fn: () => any): void;
setDisabledState(isDisabled: boolean): void;
writeValue(value: any): void; writeValue(value: any): void;
} }

View File

@ -44,6 +44,9 @@
{ {
"name": "BROWSER_MODULE_PROVIDERS" "name": "BROWSER_MODULE_PROVIDERS"
}, },
{
"name": "BaseControlValueAccessor"
},
{ {
"name": "BrowserDomAdapter" "name": "BrowserDomAdapter"
}, },
@ -1637,6 +1640,9 @@
{ {
"name": "ɵɵelementStart" "name": "ɵɵelementStart"
}, },
{
"name": "ɵɵgetInheritedFactory"
},
{ {
"name": "ɵɵinject" "name": "ɵɵinject"
}, },

View File

@ -44,6 +44,9 @@
{ {
"name": "BROWSER_MODULE_PROVIDERS" "name": "BROWSER_MODULE_PROVIDERS"
}, },
{
"name": "BaseControlValueAccessor"
},
{ {
"name": "BrowserDomAdapter" "name": "BrowserDomAdapter"
}, },
@ -1616,6 +1619,9 @@
{ {
"name": "ɵɵelementStart" "name": "ɵɵelementStart"
}, },
{
"name": "ɵɵgetInheritedFactory"
},
{ {
"name": "ɵɵinject" "name": "ɵɵinject"
}, },

View File

@ -47,51 +47,11 @@ export const CHECKBOX_VALUE_ACCESSOR: any = {
}) })
export class CheckboxControlValueAccessor extends BuiltInControlValueAccessor implements export class CheckboxControlValueAccessor extends BuiltInControlValueAccessor implements
ControlValueAccessor { ControlValueAccessor {
/**
* The registered callback function called when a change event occurs on the input element.
* @nodoc
*/
onChange = (_: any) => {};
/**
* The registered callback function called when a blur event occurs on the input element.
* @nodoc
*/
onTouched = () => {};
constructor(private _renderer: Renderer2, private _elementRef: ElementRef) {
super();
}
/** /**
* Sets the "checked" property on the input element. * Sets the "checked" property on the input element.
* @nodoc * @nodoc
*/ */
writeValue(value: any): void { writeValue(value: any): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'checked', value); this.setProperty('checked', value);
}
/**
* Registers a function called when the control value changes.
* @nodoc
*/
registerOnChange(fn: (_: any) => {}): void {
this.onChange = fn;
}
/**
* Registers a function called when the control is touched.
* @nodoc
*/
registerOnTouched(fn: () => {}): void {
this.onTouched = fn;
}
/**
* Sets the "disabled" property on the input element.
* @nodoc
*/
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
} }
} }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {InjectionToken} from '@angular/core'; import {Directive, ElementRef, InjectionToken, Renderer2} from '@angular/core';
/** /**
* @description * @description
@ -132,13 +132,75 @@ export interface ControlValueAccessor {
} }
/** /**
* Base class for all built-in ControlValueAccessor classes. We use this class to distinguish * Base class for all ControlValueAccessor classes defined in Forms package.
* between built-in and custom CVAs, so that Forms logic can recognize built-in CVAs and treat * Contains common logic and utility functions.
* custom ones with higher priority (when both built-in and custom CVAs are present). *
* Note: this is an *internal-only* class and should not be extended or used directly in * Note: this is an *internal-only* class and should not be extended or used directly in
* applications code. * applications code.
*/ */
export class BuiltInControlValueAccessor {} @Directive()
export class BaseControlValueAccessor {
/**
* The registered callback function called when a change or input event occurs on the input
* element.
* @nodoc
*/
onChange = (_: any) => {};
/**
* The registered callback function called when a blur event occurs on the input element.
* @nodoc
*/
onTouched = () => {};
constructor(private _renderer: Renderer2, private _elementRef: ElementRef) {}
/**
* Helper method that sets a property on a target element using the current Renderer
* implementation.
* @nodoc
*/
protected setProperty(key: string, value: any): void {
this._renderer.setProperty(this._elementRef.nativeElement, key, value);
}
/**
* Registers a function called when the control is touched.
* @nodoc
*/
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
/**
* Registers a function called when the control value changes.
* @nodoc
*/
registerOnChange(fn: (_: any) => {}): void {
this.onChange = fn;
}
/**
* Sets the "disabled" property on the range input element.
* @nodoc
*/
setDisabledState(isDisabled: boolean): void {
this.setProperty('disabled', isDisabled);
}
}
/**
* Base class for all built-in ControlValueAccessor classes (except DefaultValueAccessor, which is
* used in case no other CVAs can be found). We use this class to distinguish between default CVA,
* built-in CVAs and custom CVAs, so that Forms logic can recognize built-in CVAs and treat custom
* ones with higher priority (when both built-in and custom CVAs are present).
*
* Note: this is an *internal-only* class and should not be extended or used directly in
* applications code.
*/
@Directive()
export class BuiltInControlValueAccessor extends BaseControlValueAccessor {
}
/** /**
* Used to provide a `ControlValueAccessor` for form controls. * Used to provide a `ControlValueAccessor` for form controls.

View File

@ -9,7 +9,7 @@
import {ɵgetDOM as getDOM} from '@angular/common'; import {ɵgetDOM as getDOM} from '@angular/common';
import {Directive, ElementRef, forwardRef, Inject, InjectionToken, Optional, Renderer2} from '@angular/core'; import {Directive, ElementRef, forwardRef, Inject, InjectionToken, Optional, Renderer2} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor'; import {BaseControlValueAccessor, ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
export const DEFAULT_VALUE_ACCESSOR: any = { export const DEFAULT_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR, provide: NG_VALUE_ACCESSOR,
@ -83,25 +83,14 @@ export const COMPOSITION_BUFFER_MODE = new InjectionToken<boolean>('CompositionE
}, },
providers: [DEFAULT_VALUE_ACCESSOR] providers: [DEFAULT_VALUE_ACCESSOR]
}) })
export class DefaultValueAccessor implements ControlValueAccessor { export class DefaultValueAccessor extends BaseControlValueAccessor implements ControlValueAccessor {
/**
* The registered callback function called when an input event occurs on the input element.
* @nodoc
*/
onChange = (_: any) => {};
/**
* The registered callback function called when a blur event occurs on the input element.
* @nodoc
*/
onTouched = () => {};
/** Whether the user is creating a composition string (IME events). */ /** Whether the user is creating a composition string (IME events). */
private _composing = false; private _composing = false;
constructor( constructor(
private _renderer: Renderer2, private _elementRef: ElementRef, renderer: Renderer2, elementRef: ElementRef,
@Optional() @Inject(COMPOSITION_BUFFER_MODE) private _compositionMode: boolean) { @Optional() @Inject(COMPOSITION_BUFFER_MODE) private _compositionMode: boolean) {
super(renderer, elementRef);
if (this._compositionMode == null) { if (this._compositionMode == null) {
this._compositionMode = !_isAndroid(); this._compositionMode = !_isAndroid();
} }
@ -113,31 +102,7 @@ export class DefaultValueAccessor implements ControlValueAccessor {
*/ */
writeValue(value: any): void { writeValue(value: any): void {
const normalizedValue = value == null ? '' : value; const normalizedValue = value == null ? '' : value;
this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue); this.setProperty('value', normalizedValue);
}
/**
* Registers a function called when the control value changes.
* @nodoc
*/
registerOnChange(fn: (_: any) => void): void {
this.onChange = fn;
}
/**
* Registers a function called when the control is touched.
* @nodoc
*/
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
/**
* Sets the "disabled" property on the input element.
* @nodoc
*/
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
} }
/** @internal */ /** @internal */

View File

@ -48,23 +48,6 @@ export const NUMBER_VALUE_ACCESSOR: any = {
}) })
export class NumberValueAccessor extends BuiltInControlValueAccessor implements export class NumberValueAccessor extends BuiltInControlValueAccessor implements
ControlValueAccessor { ControlValueAccessor {
/**
* The registered callback function called when a change or input event occurs on the input
* element.
* @nodoc
*/
onChange = (_: any) => {};
/**
* The registered callback function called when a blur event occurs on the input element.
* @nodoc
*/
onTouched = () => {};
constructor(private _renderer: Renderer2, private _elementRef: ElementRef) {
super();
}
/** /**
* Sets the "value" property on the input element. * Sets the "value" property on the input element.
* @nodoc * @nodoc
@ -72,7 +55,7 @@ export class NumberValueAccessor extends BuiltInControlValueAccessor implements
writeValue(value: number): void { writeValue(value: number): void {
// The value needs to be normalized for IE9, otherwise it is set to 'null' when null // The value needs to be normalized for IE9, otherwise it is set to 'null' when null
const normalizedValue = value == null ? '' : value; const normalizedValue = value == null ? '' : value;
this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue); this.setProperty('value', normalizedValue);
} }
/** /**
@ -84,20 +67,4 @@ export class NumberValueAccessor extends BuiltInControlValueAccessor implements
fn(value == '' ? null : parseFloat(value)); fn(value == '' ? null : parseFloat(value));
}; };
} }
/**
* Registers a function called when the control is touched.
* @nodoc
*/
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
/**
* Sets the "disabled" property on the input element.
* @nodoc
*/
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
}
} }

View File

@ -124,16 +124,13 @@ export class RadioControlValueAccessor extends BuiltInControlValueAccessor imple
/** /**
* The registered callback function called when a change event occurs on the input element. * The registered callback function called when a change event occurs on the input element.
* Note: we declare `onChange` here (also used as host listener) as a function with no arguments
* to override the `onChange` function (which expects 1 argument) in the parent
* `BaseControlValueAccessor` class.
* @nodoc * @nodoc
*/ */
onChange = () => {}; onChange = () => {};
/**
* The registered callback function called when a blur event occurs on the input element.
* @nodoc
*/
onTouched = () => {};
/** /**
* @description * @description
* Tracks the name of the radio input element. * Tracks the name of the radio input element.
@ -156,9 +153,9 @@ export class RadioControlValueAccessor extends BuiltInControlValueAccessor imple
@Input() value: any; @Input() value: any;
constructor( constructor(
private _renderer: Renderer2, private _elementRef: ElementRef, renderer: Renderer2, elementRef: ElementRef, private _registry: RadioControlRegistry,
private _registry: RadioControlRegistry, private _injector: Injector) { private _injector: Injector) {
super(); super(renderer, elementRef);
} }
/** @nodoc */ /** @nodoc */
@ -179,7 +176,7 @@ export class RadioControlValueAccessor extends BuiltInControlValueAccessor imple
*/ */
writeValue(value: any): void { writeValue(value: any): void {
this._state = value === this.value; this._state = value === this.value;
this._renderer.setProperty(this._elementRef.nativeElement, 'checked', this._state); this.setProperty('checked', this._state);
} }
/** /**
@ -203,22 +200,6 @@ export class RadioControlValueAccessor extends BuiltInControlValueAccessor imple
this.writeValue(value); this.writeValue(value);
} }
/**
* Registers a function called when the control is touched.
* @nodoc
*/
registerOnTouched(fn: () => {}): void {
this.onTouched = fn;
}
/**
* Sets the "disabled" property on the input element.
* @nodoc
*/
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
}
private _checkName(): void { private _checkName(): void {
if (this.name && this.formControlName && this.name !== this.formControlName && if (this.name && this.formControlName && this.name !== this.formControlName &&
(typeof ngDevMode === 'undefined' || ngDevMode)) { (typeof ngDevMode === 'undefined' || ngDevMode)) {

View File

@ -52,29 +52,12 @@ export const RANGE_VALUE_ACCESSOR: StaticProvider = {
}) })
export class RangeValueAccessor extends BuiltInControlValueAccessor implements export class RangeValueAccessor extends BuiltInControlValueAccessor implements
ControlValueAccessor { ControlValueAccessor {
/**
* The registered callback function called when a change or input event occurs on the input
* element.
* @nodoc
*/
onChange = (_: any) => {};
/**
* The registered callback function called when a blur event occurs on the input element.
* @nodoc
*/
onTouched = () => {};
constructor(private _renderer: Renderer2, private _elementRef: ElementRef) {
super();
}
/** /**
* Sets the "value" property on the input element. * Sets the "value" property on the input element.
* @nodoc * @nodoc
*/ */
writeValue(value: any): void { writeValue(value: any): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'value', parseFloat(value)); this.setProperty('value', parseFloat(value));
} }
/** /**
@ -86,20 +69,4 @@ export class RangeValueAccessor extends BuiltInControlValueAccessor implements
fn(value == '' ? null : parseFloat(value)); fn(value == '' ? null : parseFloat(value));
}; };
} }
/**
* Registers a function called when the control is touched.
* @nodoc
*/
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
/**
* Sets the "disabled" property on the range input element.
* @nodoc
*/
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
}
} }

View File

@ -99,18 +99,6 @@ export class SelectControlValueAccessor extends BuiltInControlValueAccessor impl
/** @internal */ /** @internal */
_idCounter: number = 0; _idCounter: number = 0;
/**
* The registered callback function called when a change event occurs on the input element.
* @nodoc
*/
onChange = (_: any) => {};
/**
* The registered callback function called when a blur event occurs on the input element.
* @nodoc
*/
onTouched = () => {};
/** /**
* @description * @description
* Tracks the option comparison algorithm for tracking identities when * Tracks the option comparison algorithm for tracking identities when
@ -126,10 +114,6 @@ export class SelectControlValueAccessor extends BuiltInControlValueAccessor impl
private _compareWith: (o1: any, o2: any) => boolean = Object.is; private _compareWith: (o1: any, o2: any) => boolean = Object.is;
constructor(private _renderer: Renderer2, private _elementRef: ElementRef) {
super();
}
/** /**
* Sets the "value" property on the input element. The "selectedIndex" * Sets the "value" property on the input element. The "selectedIndex"
* property is also set if an ID is provided on the option element. * property is also set if an ID is provided on the option element.
@ -139,10 +123,10 @@ export class SelectControlValueAccessor extends BuiltInControlValueAccessor impl
this.value = value; this.value = value;
const id: string|null = this._getOptionId(value); const id: string|null = this._getOptionId(value);
if (id == null) { if (id == null) {
this._renderer.setProperty(this._elementRef.nativeElement, 'selectedIndex', -1); this.setProperty('selectedIndex', -1);
} }
const valueString = _buildValueString(id, value); const valueString = _buildValueString(id, value);
this._renderer.setProperty(this._elementRef.nativeElement, 'value', valueString); this.setProperty('value', valueString);
} }
/** /**
@ -156,22 +140,6 @@ export class SelectControlValueAccessor extends BuiltInControlValueAccessor impl
}; };
} }
/**
* Registers a function called when the control is touched.
* @nodoc
*/
registerOnTouched(fn: () => any): void {
this.onTouched = fn;
}
/**
* Sets the "disabled" property on the select input element.
* @nodoc
*/
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
}
/** @internal */ /** @internal */
_registerOption(): string { _registerOption(): string {
return (this._idCounter++).toString(); return (this._idCounter++).toString();

View File

@ -95,18 +95,6 @@ export class SelectMultipleControlValueAccessor extends BuiltInControlValueAcces
/** @internal */ /** @internal */
_idCounter: number = 0; _idCounter: number = 0;
/**
* The registered callback function called when a change event occurs on the input element.
* @nodoc
*/
onChange = (_: any) => {};
/**
* The registered callback function called when a blur event occurs on the input element.
* @nodoc
*/
onTouched = () => {};
/** /**
* @description * @description
* Tracks the option comparison algorithm for tracking identities when * Tracks the option comparison algorithm for tracking identities when
@ -122,10 +110,6 @@ export class SelectMultipleControlValueAccessor extends BuiltInControlValueAcces
private _compareWith: (o1: any, o2: any) => boolean = Object.is; private _compareWith: (o1: any, o2: any) => boolean = Object.is;
constructor(private _renderer: Renderer2, private _elementRef: ElementRef) {
super();
}
/** /**
* Sets the "value" property on one or of more of the select's options. * Sets the "value" property on one or of more of the select's options.
* @nodoc * @nodoc
@ -179,22 +163,6 @@ export class SelectMultipleControlValueAccessor extends BuiltInControlValueAcces
}; };
} }
/**
* Registers a function called when the control is touched.
* @nodoc
*/
registerOnTouched(fn: () => any): void {
this.onTouched = fn;
}
/**
* Sets the "disabled" property on the select input element.
* @nodoc
*/
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
}
/** @internal */ /** @internal */
_registerOption(value: ɵNgSelectMultipleOption): string { _registerOption(value: ɵNgSelectMultipleOption): string {
const id: string = (this._idCounter++).toString(); const id: string = (this._idCounter++).toString();