Angular2 v.2.3 - Имейте директивный доступ к FormControl, созданному с помощью синтаксиса formControlName
Итак, я пытаюсь создать директиву, которая может манипулировать FormControl.
Похоже, что если я использую длинный синтаксис для объявления элементов управления формы в шаблоне, я могу передать элемент управления директиве, чтобы делать вещи с ним как прямую привязку @Input(); т.е. со следующим шаблоном:
<form [formGroup]="myForm">
<input type="text" id="myText" [formControl]="myForm.controls['myText']" my-directive>
</form>
И следующая логика компонента:
@Component({
// Properties go here.
})
class MyComponent {
myForm: FormGroup;
constructor(fb: FormBuilder) {
// Constructor logic...
}
ngOnInit() {
this.myForm = this.fb.group({
"myText": [""]
});
}
}
Директива будет выглядеть так:
@Directive({
selector: "[my-directive]"
})
class MyDirective {
Input() formControl: FormControl;
}
Но если бы я использовал синтаксис formControlName в шаблоне:
<form [formGroup]="myForm">
<input type="text" id="myText" formControlName="myText" my-directive>
</form>
Как я могу ссылаться (неявно?), сделанный FormControl в директиве?
Ответы
Ответ 1
Если вы используете NgControl
, ElementRef
, HostListener
и инъекцию конструктора, мы можем иметь директиву, применимую к элементам управления формами из реактивных форм в формах formControlName
или [formControl]
и даже с шаблонами:
import { Directive, ElementRef, HostListener } from "@angular/core";
import { NgControl } from "@angular/forms";
@Directive({
selector: '[my-directive]'
})
export class MyDirective {
constructor(private el: ElementRef, private control : NgControl) { }
@HostListener('input',['$event']) onEvent($event){
let valueToTransform = this.el.nativeElement.value;
// do something with the valueToTransform
this.control.control.setValue(valueToTransform);
}
}
Здесь применимая демонстрация
Ответ 2
Ответ @silentsod будет работать безупречно.
1. если вам нужно обрабатывать несколько событий, таких как нажатие клавиши вверх/вниз или любые другие события, вы можете перейти к подходу ниже. 2. Кроме того, лучше определить события в самой директиве.
import { Directive, ElementRef} from "@angular/core";
import { NgControl } from "@angular/forms";
@Directive({
selector: '[my-directive]',
host: {
'(input)':'onEvent($event)',
'(keydown.backspace)': 'onEvent($event, true)'
})
export class MyDirective {
constructor(private el: ElementRef, private control : NgControl) { }
public onEvent($event, someEvent){
let valueToTransform = this.el.nativeElement.value;
// do something with the valueToTransform
if(someEvent) {
//do something
}
this.control.control.setValue(valueToTransform);
}
}
В Html
<form [formGroup]="myForm">
<input type="text" id="myText" formControlName="myText" my-directive>
</form>