angular - Bộ kiểm tra của tôi đang báo 'không hợp lệ' mặc dù thực tế nó không phải
Hiện tại tôi đang tạo một trường văn bản, trường này không được để trống và cũng không được phép bắt đầu bằng một chuỗi ký tự cụ thể. (giả sử là 'test')
Vì vậy ví dụ, tôi muốn testxyz hoặc là không hợp lệ và mọi thứ khác là hợp lệ. Tôi đã có RegExp: /^((?!(test)).)*$/gmi. Tôi biết một cái gì đó như abctest cũng không hợp lệ, nhưng điều đó không quan trọng trong trường hợp này.
Vấn đề là một khi tôi gửi một đầu vào không hợp lệ, mỗi lần tôi nhập một chuỗi có số ký tự chẵn (!) thì trình xác thực lại nói rằng đó là đầu vào không hợp lệ (nó in ra 'Lỗi 2'; bạn có thể thấy nơi mà điều đó được in ra trong HTML) mặc dù nó không phải là như vậy!
Vì vậy, ví dụ, nếu tôi viết test trước, nó sẽ báo lỗi nói rằng nó không hợp lệ. Đúng. Nếu tôi sau đó viết bất kỳ ký tự nào, như a, nó sẽ không báo lỗi. Cũng đúng. Nhưng ngay khi tôi viết một số lượng ký tự chẵn, bất kể là gì (!), như aa hoặc wxyz, nó lại báo lỗi trong khi không nên như vậy!
Dù sao thì tôi cũng có thể gửi nó và mọi thứ đang hoạt động, chỉ là nhận định sai 'diễn giải' của trình xác nhận và tôi không hiểu tại sao nó lại làm như vậy. Có lẽ ai đó có thể giúp tôi. Tôi đã thêm mã bên dưới.
HTML :
<h1 mat-dialog-title>{{data.dialogTitle}}</h1>
<div mat-dialog-content>
<p class="mat-typography">{{data.dialogText}}</p>
</div>
<mat-form-field>
<input matInput [(ngModel)]="name" placeholder="Enter your name?" [formControl]="InputControl">
<mat-error *ngIf='InputControl.hasError("required")'>
Error 1
</mat-error>
<mat-error *ngIf='InputControl.hasError("pattern")'>
Error 2
</mat-error>
</mat-form-field>
<mat-dialog-actions>
<span style="flex: 1 1 auto"></span>
<button mat-flat-button (click)="pressed()" class="mat-primary">OK</button>
</mat-dialog-actions>
TypeScript :
export class DialogComponent {
regExp = /^((?!(test)).)*$/gmi;
InputControl = new FormControl("", [Validators.required, Validators.pattern(this.regExp)])
@Input() name:string
constructor(public dialogRef: MatDialogRef<DialogComponent>,
@Optional() @Inject(MAT_DIALOG_DATA) public data: any) { }
pressed() {
console.log(this.name.match(this.regExp));
if(this.regExp.test(this.name)) {
alert("valid");
this.dialogRef.close(true);
}
}
}
Cảm ơn trước.
Câu trả lời #1
Nguyên nhân gốc rễ nằm ở các ngữ cảnh thực thi. Trong hàm Validators.pattern của bạn, bạn đang tham chiếu đến tham số của nó thông qua this.regExp, nhưng hàm này sẽ không được thực thi trong phạm vi của controller hiện tại và kết quả là this sẽ không trỏ đến controller của bạn mà đến một số thành phần nội bộ của Angular trong lớp InputControl trong trường hợp này. Nói một cách đơn giản, bạn đã mất this.
Để thay đổi giải pháp nhanh chóng và tạm thời:
Validators.pattern(this.regExp)
đến :
Validators.pattern(/^((?!(test)).)*$/gmi)
Và kiểm tra xem, nếu những điều đó có giúp.
Nếu có, thì nếu bạn vẫn muốn lưu mẫu trong bộ điều khiển, về cơ bản bạn phải bao bọc hàm xác thực của mình trong một hàm bộ điều khiển khác để đóng gói mẫu trong phạm vi closure, điều này sẽ có sẵn cho hàm trong bối cảnh thực thi:
getMyValidation(): (AbstractControl): ValidationErrors | null {
let pattern = this.regExp;
return Validators.pattern(pattern)
}
và truyền nó vào trình tạo biểu mẫu như sau:
InputControl = new FormControl("", [Validators.required, this.getMyValidation()])
Câu trả lời #2
Được rồi, rõ ràng là tôi đã tự tìm ra lỗi. Nó liên quan đến các cờ mà tôi đã sử dụng. gmi
Tôi đã bỏ 'g' và bây giờ nó hoạt động. Tôi nghĩ điều đó có liên quan đến cách các đối tượng RegExp hoạt động. Khi bạn sử dụng cờ 'g', đối tượng sẽ theo dõi lastIndex, nơi một kết quả khớp xảy ra, vì vậy các kết quả khớp tiếp theo sẽ bắt đầu từ đó. Nếu bạn bỏ cờ 'g', nó cơ bản đặt nó về zero sau một kết quả khớp và do đó giải quyết vấn đề của tôi. Tuy nhiên, tôi chưa chắc chắn 100% về điều đó.
