I've been create a simple custom input
component in my angular app use ControlValueAccessor
. So, when I want to create a form input
element, I don't have to call <input />
, only call <my-input>
.
I have a problem, when I use <input />
, I can use myDirective
. For example:
<input type="text" class="form-control" formControlName="name" myDirective />
But, when I use my-input
, then I can't use myDirective
. For example:
<my-input formControlName="name" myDirective></my-input>
myDirective dosn't work in my-input
This is my-input
component use ControlValueAccessor
code:
import { Component, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
@Component({
selector: 'my-input',
templateUrl: './my-input.component.html',
styleUrls: ['./my-input.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MyInputComponent ),
multi: true
}
]
})
export class MyInputComponent implements ControlValueAccessor {
onChange: () => void;
onTouched: () => void;
value: string;
writeValue(value: string): void {
this.value = value ? value : '';
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
}
Updated: myDirective
code:
import { Directive, HostListener } from '@angular/core';
import { FormControlName } from '@angular/forms';
@Directive({
selector: '[myDirective]'
})
export class MyDirective{
constructor(private formControlName: FormControlName) { }
@HostListener('input', ['$event'])
onInputChange() {
this.formControlName.control.setValue(this.formControlName.value.replace(/[^0-9]/g, ''));
}
}
Is there a way for myDirective
to be used in themy-input
component?
Thanks in advance.
There're a problem with your directive. Inject a NgControl and control this ngControl
export class MyDirective{
constructor(private control: NgControl) { } //<--inject NgControl
@HostListener('input', ['$event'])
onInputChange() {
this.control.control.setValue(this.control.value.replace(/[^0-9]/g, ''));
}
}
You can see in stackblitz
NOTE: Don't forget include in the module declarations
@NgModule({
imports: [ BrowserModule, FormsModule,ReactiveFormsModule ],
declarations: [ AppComponent, MyInputComponent,MyDirective ],
bootstrap: [ AppComponent ]
})
export class AppModule { }