在 Angular 7 中从现有函数创建用于验证的自定义指令?
Creating Custom Directives for Validation in Angular 7 from an existing function?
我在理解如何需要在 Angular 中创建自定义指令时遇到了一些困难。我有一个输入字段,用户需要输入一串字符,但它需要检查该字符串是否不包含某些子字符串。到目前为止,我已经完成了这个功能:
checkInvalidStrings(value, invalidValues) {
let isKbWalk;
let amount = [];
invalidValues.forEach(string => {
if (value.indexOf(string) > -1) {
amount.push(string);
}
})
if (amount.length < 4) {
isKeyboardWalk = false;
} else {
isKbWalk = true;
}
return isKbWalk;
}
我可以 运行 在组件文件中更改 ngModel 中的这个并且它完美地工作,我遇到的问题是我想 link 它与表单验证,所以如果它returns false,我希望它有效,如果它 returns true,我希望它无效。我相信我需要为此创建一个自定义验证器指令,但我遇到了一些麻烦。我想我要问的是如何使用上面的函数,以便我可以将它实现为一个指令来确定它是否有效?我正在使用模板驱动的表单,因为这是构建应用程序的方式,在这一点上保持一致比更改为响应式表单更简单。
通常我希望能够像这样对输入做一些事情,其中 kbWalk 是检查输入字段是否存在无效字符串的指令:
<input [(ngModel)]="data.newValue" name="newValue" #newValue="ngModel" required kbWalk>
到目前为止,我已将所有内容导入 app.module 文件,但验证工作不正常,这是我的指令设置:
import { Directive, forwardRef, Attribute } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
import { Invalid } from './invalidStrings';
@Directive({
selector: '[kbWalk][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: KeyboardWalkValidator, multi: true }
]
})
export class KeyboardWalkValidator implements Validator {
invalidStrings = Invalid.strings;
constructor() { }
validate(c: AbstractControl): { [key: string]: any } {
return null;
}
}
感谢您的帮助!
已解决:
import { Directive, forwardRef, Attribute, Input } from '@angular/core';
import { Validator, FormControl, NG_VALIDATORS } from '@angular/forms';
import { Invalid } from '../components/common/Invalid';
@Directive({
selector: '[isKeyboardWalk][formControlName],[isKeyboardWalk][formControl],[isKeyboardWalk][ngModel]',
providers: [ { provide: NG_VALIDATORS, useExisting: KeyboardWalkValidator, multi: true }
]
})
export class KeyboardWalkValidator implements Validator {
invalid = Invalid.array;
validate(c: FormControl): { [key: string]: any } {
const val = c.value;
return this.checkInvalidStrings(val) ? {'isKeyboardWalk': true} : null;
}
checkInvalidStrings(value) {
// code for checking invalid value
}
}
然后在视图中我只使用 isKeyboardWalk 指令:
<input type="text" isKeyboardWalk/>
我的问题是理解传递给验证函数的值实际上是来自表单的值,所以我可以在我的 checkInvalidStrings() 函数中将该值用于 运行 并且它工作正常.如果你们有选择,我会建议使用 Reactive Forms 并在下面的评论中实施解决方案,这也非常简单,帮助我了解更多。
我们可以使用自定义验证器来实现上述目的(我认为我们不需要为上述创建自定义指令)。以下对我有用。
customValidatorTest.ts 文件
import { AbstractControl } from '@angular/forms';
export function ValidateUrl(control: AbstractControl) {
if ( !control.value.includes('.io')) {
return { validUrl: true };
}
return null;
}
component.ts 文件
import { FormGroup, FormArray, FormBuilder,FormControl, Validators } from '@angular/forms';
import { ValidateUrl } from '../../customValidatorTest';
@Component({
selector: 'app-educational-details',
templateUrl: './educational-details.component.html',
styleUrls: ['./educational-details.component.css']
})
export class EducationalDetailsComponent implements OnInit {
educationalForm: FormGroup;
constructor(private formBuilder: FormBuilder){}
ngOnInit() {
this.educationalForm= this.formBuilder.group({
branch:['',[Validators.required,ValidateUrl]]
})
}
}
component.html 文件
// adding only required functionality you directly write formGrop also
<tbody formArrayName="educationalDetails">
<tr *ngFor="let educationalDetail of educationalForm.controls.educationalDetails.controls; let $i=index" [formGroupName]="$i">
<td><input type="text" class="form-control my-1" formControlName="branch" ></td> //if branch input text box doesnt contain ".io" then it is invalid otherwise valid
关注 link 可能会有帮助
我在理解如何需要在 Angular 中创建自定义指令时遇到了一些困难。我有一个输入字段,用户需要输入一串字符,但它需要检查该字符串是否不包含某些子字符串。到目前为止,我已经完成了这个功能:
checkInvalidStrings(value, invalidValues) {
let isKbWalk;
let amount = [];
invalidValues.forEach(string => {
if (value.indexOf(string) > -1) {
amount.push(string);
}
})
if (amount.length < 4) {
isKeyboardWalk = false;
} else {
isKbWalk = true;
}
return isKbWalk;
}
我可以 运行 在组件文件中更改 ngModel 中的这个并且它完美地工作,我遇到的问题是我想 link 它与表单验证,所以如果它returns false,我希望它有效,如果它 returns true,我希望它无效。我相信我需要为此创建一个自定义验证器指令,但我遇到了一些麻烦。我想我要问的是如何使用上面的函数,以便我可以将它实现为一个指令来确定它是否有效?我正在使用模板驱动的表单,因为这是构建应用程序的方式,在这一点上保持一致比更改为响应式表单更简单。
通常我希望能够像这样对输入做一些事情,其中 kbWalk 是检查输入字段是否存在无效字符串的指令:
<input [(ngModel)]="data.newValue" name="newValue" #newValue="ngModel" required kbWalk>
到目前为止,我已将所有内容导入 app.module 文件,但验证工作不正常,这是我的指令设置:
import { Directive, forwardRef, Attribute } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
import { Invalid } from './invalidStrings';
@Directive({
selector: '[kbWalk][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: KeyboardWalkValidator, multi: true }
]
})
export class KeyboardWalkValidator implements Validator {
invalidStrings = Invalid.strings;
constructor() { }
validate(c: AbstractControl): { [key: string]: any } {
return null;
}
}
感谢您的帮助!
已解决:
import { Directive, forwardRef, Attribute, Input } from '@angular/core';
import { Validator, FormControl, NG_VALIDATORS } from '@angular/forms';
import { Invalid } from '../components/common/Invalid';
@Directive({
selector: '[isKeyboardWalk][formControlName],[isKeyboardWalk][formControl],[isKeyboardWalk][ngModel]',
providers: [ { provide: NG_VALIDATORS, useExisting: KeyboardWalkValidator, multi: true }
]
})
export class KeyboardWalkValidator implements Validator {
invalid = Invalid.array;
validate(c: FormControl): { [key: string]: any } {
const val = c.value;
return this.checkInvalidStrings(val) ? {'isKeyboardWalk': true} : null;
}
checkInvalidStrings(value) {
// code for checking invalid value
}
}
然后在视图中我只使用 isKeyboardWalk 指令:
<input type="text" isKeyboardWalk/>
我的问题是理解传递给验证函数的值实际上是来自表单的值,所以我可以在我的 checkInvalidStrings() 函数中将该值用于 运行 并且它工作正常.如果你们有选择,我会建议使用 Reactive Forms 并在下面的评论中实施解决方案,这也非常简单,帮助我了解更多。
我们可以使用自定义验证器来实现上述目的(我认为我们不需要为上述创建自定义指令)。以下对我有用。
customValidatorTest.ts 文件
import { AbstractControl } from '@angular/forms';
export function ValidateUrl(control: AbstractControl) {
if ( !control.value.includes('.io')) {
return { validUrl: true };
}
return null;
}
component.ts 文件
import { FormGroup, FormArray, FormBuilder,FormControl, Validators } from '@angular/forms';
import { ValidateUrl } from '../../customValidatorTest';
@Component({
selector: 'app-educational-details',
templateUrl: './educational-details.component.html',
styleUrls: ['./educational-details.component.css']
})
export class EducationalDetailsComponent implements OnInit {
educationalForm: FormGroup;
constructor(private formBuilder: FormBuilder){}
ngOnInit() {
this.educationalForm= this.formBuilder.group({
branch:['',[Validators.required,ValidateUrl]]
})
}
}
component.html 文件
// adding only required functionality you directly write formGrop also
<tbody formArrayName="educationalDetails">
<tr *ngFor="let educationalDetail of educationalForm.controls.educationalDetails.controls; let $i=index" [formGroupName]="$i">
<td><input type="text" class="form-control my-1" formControlName="branch" ></td> //if branch input text box doesnt contain ".io" then it is invalid otherwise valid
关注 link 可能会有帮助