Angular 角度:从指令访问FormControl
我想通过自定义指令将验证器动态添加到我的FormControl中Angular 角度:从指令访问FormControl,angular,typescript,angular-directive,Angular,Typescript,Angular Directive,我想通过自定义指令将验证器动态添加到我的FormControl中 @Directive({ selector: "[idNumber]", }) export class IdNumberDirective implements OnInit { constructor(private formControl: FormControl) { } ngOnInit() { this.addValidators(this.formControl);
@Directive({
selector: "[idNumber]",
})
export class IdNumberDirective implements OnInit {
constructor(private formControl: FormControl) { }
ngOnInit() {
this.addValidators(this.formControl);
}
addValidators(formControl: FormControl) {
formControl.setValidators(Validators.compose(
[Validators.required,
Validators.minLength(3),
Validators.maxLength(8)
]
));
}
<mat-form-field>
<mat-label>{{label}}</mat-label>
<input matInput
[formControl]="idNumberFormControl"
[placeholder]="placeholder"
</mat-form-field>
@指令({
选择器:“[idNumber]”,
})
将类IdNumberDirective实现导出到NIT{
构造函数(私有formControl:formControl){}
恩戈尼尼特(){
this.addValidators(this.formControl);
}
addValidators(formControl:formControl){
formControl.setValidators(Validators.compose(
[验证器。必需,
验证器。最小长度(3),
Validators.maxLength(8)
]
));
}
{{label}}
如果您使用NgControl和构造函数DI注入,我们可以在formControlName或模板驱动的表单中使用适用于反应式表单的表单控件的指令:
指令:
import { Directive } from "@angular/core";
import { NgControl } from "@angular/forms";
@Directive({
selector: '[my-directive]'
})
export class MyDirective {
constructor(private el: ElementRef, private control : NgControl) { }
}
下面是一个使用指令将验证器附加到表单控件的示例
请注意,使用它将导致丢失所有以前的验证器
constructor(
// Get the control directive
private control: NgControl
) { }
ngOnInit() {
const abstractControl = this.control.control;
abstractControl && abstractControl.setValidators([Validators.required]);
}
//TestAnythingsComponent.ts
从“@angular/core”导入{Component,OnInit};
从'@angular/forms'导入{FormControl,FormBuilder,FormGroup,Validators};
从“../directions/IdNumberDirective.directive”导入{IdNumberDirective};
@组成部分({
选择器:“应用程序测试任何东西”,
templateUrl:“./testanythings.component.html”,
styleUrls:['./testanythings.component.css'],
提供者:[IdNumberDirective]
})
导出类TestAnythingsComponent实现OnInit{
testForm:FormGroup;
构造函数(fb:FormBuilder,IdNumberDirective:IdNumberDirective){
this.testForm=fb.group({
idNumberFormControl:new FormControl(空,
验证器([
需要验证器,
验证器。最小长度(3),
验证程序。最大长度(8),
IdNumberDirective.customValidator()
])
),
})
}
}
//IdNumberDirective.ts
从'@angular/core'导入{指令,OnInit};
从'@angular/forms'导入{Validators,ValidatorFn,AbstractControl,ValidationErrors};
@指示({
选择器:“[idNumber]”
})
将类IdNumberDirective实现导出到NIT{
构造函数(){
}
恩戈尼尼特(){
}
customValidator():验证器fn{
验证器。空验证器
返回(控件:AbstractControl):ValidationErrors | null=>{
//检查控制值的任何条件
if(control.value!=“Sachin”){
//返回错误的键值对
返回{“customError”:{inValid:true,errMsg:'inValid Value'};
}
返回null;
}
}
}
//test-anythings.component.html
{{testForm.get('idNumberFormControl').errors.customError.errMsg}}
提交
Hi@Suresh,谢谢你的建议,但我需要更详细的解释。我能做到吗?this.addValidators(this.control);这样行吗?PS:我不使用,也永远不会使用“模板驱动表单”。我们可以使用NgControl通过DI获取对表单控件实例的引用。您可以使用该实例访问表单控件方法。您可以用更多代码更新您的答案吗?另外-您的建议中的“private el:ElementRef”有什么意义n?嗨,OneEvent不是每次都会在FormControl的valueChanges上触发吗?我的意思是,当用户在FormControl中集中注意力时,不是每次按下任何键时都会触发此事件吗?难道没有办法在指令的OnInit方法中检查和设置这些验证器吗?谢谢。是的,它会在每次按键时触发,但是函数中的条件阻止多次设置验证器。必须这样做,因为构造函数不知道控件。您也可以使用ngOnInit(),正如我在其中使用更新我的答案一样(因为它确实更清楚!)太棒了!这正是我想要的!谢谢!这个答案非常有效,但我认为主要方面(使用NgControl
而不是OP的FormControl
)太有价值了,不能停留在外部链接中(Stackblitz)。我建议我们把这部分直接放在答案中,就像@Suresh在他的答案中一样。亲爱的Sachin,你能对你的代码发表一些评论以帮助理解你的方法吗?嗨,Artem,看看我上面的解决方案,请输入“Sachin”以消除错误消息,我已经尽了最大努力,我是angular的新手。谢谢。
constructor(
// Get the control directive
private control: NgControl
) { }
ngOnInit() {
const abstractControl = this.control.control;
abstractControl && abstractControl.setValidators([Validators.required]);
}
//TestAnythingsComponent.ts
import { Component, OnInit } from '@angular/core';
import { FormControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { IdNumberDirective } from '../directives/IdNumberDirective.directive';
@Component({
selector: 'app-test-anythings',
templateUrl: './test-anythings.component.html',
styleUrls: ['./test-anythings.component.css'],
providers:[IdNumberDirective]
})
export class TestAnythingsComponent implements OnInit {
testForm: FormGroup;
constructor(fb: FormBuilder, IdNumberDirective : IdNumberDirective) {
this.testForm = fb.group({
idNumberFormControl : new FormControl(null,
Validators.compose([
Validators.required,
Validators.minLength(3),
Validators.maxLength(8),
IdNumberDirective.customValidator()
])
),
})
}
}
//IdNumberDirective.ts
import { Directive, OnInit } from '@angular/core';
import { Validators, ValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms';
@Directive({
selector: '[idNumber]'
})
export class IdNumberDirective implements OnInit {
constructor() {
}
ngOnInit() {
}
customValidator(): ValidatorFn {
Validators.nullValidator
return (control: AbstractControl): ValidationErrors | null => {
//any condition to check control value
if (control.value != "Sachin") {
//return key value pair of errors
return { "customError": { inValid: true, errMsg: 'Invalid Value' } };
}
return null;
}
}
}
//test-anythings.component.html
<form [formGroup]="testForm">
<input idNumber formControlName="idNumberFormControl" />
<div *ngIf="testForm.get('idNumberFormControl').invalid && testForm.get('idNumberFormControl').errors.customError.inValid"
style="color:red">
{{testForm.get('idNumberFormControl').errors.customError.errMsg}}
</div>
<button type="submit">submit</button>
</form>