所以我正在做这个角度反应形式的项目,我有一个有趣的问题。 我的任务是在无效的每个表单输入下方显示一个跨度的验证错误。表单输入应在点击时进行验证,表单应在提交时进行验证。 我需要在outclick上呈现span元素,但同时,如果我从未在任何输入中输入任何内容并提交表单,则应该呈现相同的span。 因此,或者我输入了一些无效的内容,然后窗体用一个跨度告诉了我,或者单击了Submit按钮,窗体显示了每个无效输入的范围。 我希望以编程方式添加所有范围,但是通过模板也应该很好。 我的逻辑是将所有“错误”(基本上是每个跨度的内容)保存到数组中,并将所有状态保存到数组中,并通过循环和模板绑定显示它们。 我既无法弄清楚我的想法的逻辑,也无法弄清简单的解决方案。请帮助我。
我的模板:
<form class="form" [formGroup]="signUpForm" (ngSubmit)="onSubmit()">
<div class="form__group form__group--name">
<div class="form__control form__first-name">
<input type="text" name="Fname" required formControlName="firstName" a-ngblur="onBlur(true)">
<label>First Name</label>
</div>
<div class="form__control form__last-name">
<input type="text" name="Lname" required formControlName="lastName">
<label>Last Name</label>
</div>
</div>
<div class="form__group form__group--id">
<div class="form__control form__email">
<input type="text" name="email" required formControlName="email">
<label>Email ID</label>
</div>
<div class="form__control form__ID">
<input type="text" name="ID" required formControlName="id">
<label>Your User ID</label>
</div>
</div>
<div class="form__group form__group--location form-group">
<div class="form__control form__country">
<span>Country</span>
<select class="form-control" name="country" formControlName="country" (change)="onChange()" (click)="onOpen('country')">
<option [value]="null" disabled>Choose your country</option>
<option *ngFor="let country of countries" [value]="country.value">{{ country.value }}</option>
</select>
</div>
<div class="form__control form__location">
<div class="form__location--state" [ngSwitch]="this.signUpForm.get('country').value">
<span>State</span>
<select name="state" formControlName="state" *ngSwitchCase="'USA'">
<option [value]="null" disabled>Choose state</option>
<option *ngFor="let state of statesUSA" [value]="state.value">{{ state.value }}</option>
</select>
<select name="state" formControlName="state" *ngSwitchCase="'India'">
<option [value]="null" disabled>Choose state</option>
<option *ngFor="let state of statesIndia" [value]="state.value">{{ state.value }}</option>
</select>
<select name="state" formControlName="state" *ngSwitchCase="undefined">
<option [value]="null" disabled>Choose state</option>
</select>
</div>
<div class="form__location--city" [ngSwitch]="this.signUpForm.get('state').value">
<span>City</span>
<select name="city" formControlName="city" *ngSwitchCase="'New York'">
<option [value]="null" disabled>Choose city</option>
<option *ngFor="let city of citiesNY" [value]="city.value">{{ city.value }}</option>
</select>
<select name="city" formControlName="city" *ngSwitchCase="'California'">
<option [value]="null" disabled>Choose city</option>
<option *ngFor="let city of citiesCali" [value]="city.value">{{ city.value }}</option>
</select>
<select name="city" formControlName="city" *ngSwitchCase="'Andhra Pradesh'">
<option [value]="null" disabled>Choose city</option>
<option *ngFor="let city of citiesAndhra" [value]="city.value">{{ city.value }}</option>
</select>
<select name="city" formControlName="city" *ngSwitchCase="'Goa'">
<option [value]="null" disabled>Choose city</option>
<option *ngFor="let city of citiesGoa" [value]="city.value">{{ city.value }}</option>
</select>
<select name="city" formControlName="city" *ngSwitchCase="undefined">
<option [value]="null" disabled>Choose city</option>
</select>
</div>
</div>
</div>
<div class="form__group form__control--data">
<div class="form__control form__phone">
<input type="text" name="phone" required formControlName="phone" #phoneInput
[imask]="{mask: '+{38}(000)000-00-00'}" [unmask]="true">
<label>Phone Number</label>
</div>
<div class="form__control form__code">
<input type="text" name="code" class="ref-code" formControlName="code" style="text-transform: uppercase;">
<label>Reference Code</label>
</div>
</div>
<div class="form__group form__group--buttons">
<a type="button" (click)="onReset()" class="form__group--buttons-reset">Reset All</a>
<button type="submit" class="form__group--buttons-submit">Continue</button>
</div>
</form>
我的TS:
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { FormGroup, FormControl, FormArray, Validators } from '@angular/forms';
import { storageService } from '../storage-service.component';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.scss']
})
export class FormComponent implements OnInit {
signUpForm: FormGroup;
countries = [
new FormControl('USA'),
new FormControl('India')
];
statesUSA = [new FormControl('New York'), new FormControl('California')];
statesIndia = [new FormControl('Andhra Pradesh'), new FormControl('Goa')]
citiesNY = [new FormControl('Albany'), new FormControl('New York City')];
citiesCali = [new FormControl('Sacramento'), new FormControl('Los Angeles'), new FormControl('San Francisco')];
citiesAndhra = [new FormControl('Visakhapatnam'), new FormControl('Amaravati')];
citiesGoa = [new FormControl('Panaji'), new FormControl('Vasco da Gama')];
@ViewChild('phoneInput', {static: false}) phoneInput: ElementRef;
public mask:any = {
mask: '+{38}(0__)000-00-00',
lazy: false
}
invalidMessages = ['This field is required and has to contain 2-32 cyrillic characters!',
'This field is required and has to be a valid email address!',
'This is a required field!',
'This is a required field! Please enter your telephone number, formated as "0__-___-__-__"',
'This field is required and has to contain 2-32 cyrillic characters',
'This is a required field! It has to contain from 5 to 30 latin characters and "_"',
'This is a required field!',
'This is a required field!',
'This field has to contain from 1 to 10 latin characters or numbers.'];
public statusArr : string[] = [];
constructor(private storageService: storageService) { }
ngOnInit() {
this.signUpForm = new FormGroup({
'firstName': new FormControl(null, [Validators.required, Validators.pattern(/^[а-яА-ЯёЁіІїЇ]{2,32}$/iu)]),
'email': new FormControl(null, [Validators.required, Validators.email, Validators.pattern(/^\S{2,255}@\S+\.\S+$/iu)]),
'country': new FormControl(null, Validators.required),
'phone': new FormControl(null),
'lastName': new FormControl(null, [Validators.required, Validators.pattern(/^[а-яА-ЯёЁіІїЇ]{2,32}$/iu)]),
'id': new FormControl(null, [Validators.required, Validators.pattern(/\b[A-Za-z_]{5,30}\b/)]),
'state': new FormControl(null, Validators.required),
'city': new FormControl(null, Validators.required),
'code': new FormControl(null, [Validators.pattern(/\b[A-Za-z_0-9]{1,10}\b/)])
});
if(this.storageService.savedForm) this.signUpForm.setValue(this.storageService.savedForm);
}
onSubmit() {
if(this.signUpForm.status === 'VALID') {
this.storageService.savedForm = this.signUpForm.value;
console.log(this.signUpForm);
} else {
let namesArr = Object.keys(this.signUpForm.controls);
console.log(namesArr);
for(let i = 0; i < namesArr.length; i++) {
this.statusArr.push(this.signUpForm.controls[namesArr[i]].status);
}
console.log(this.statusArr);
}
}
onReset() {
}
onChange() {
(<FormGroup>this.signUpForm.get('state').value) = null;
(<FormGroup>this.signUpForm.get('city').value) = null;
}
onOpen(controlName: string) {
}
}
答案 0 :(得分:1)
请尝试以下这种方法,我仅对一种表单控件进行了处理,如果可以的话,也可以对所有其他控件进行添加。 在HTML中
<div class="form__control form__first-name">
<input type="text" name="Fname" required formControlName="firstName" a-ngblur="onBlur(true)">
<label>First Name</label>
<span *ngIf="firstname.errors.required && firstname.touched">This field is required</span>
<span *ngIf="firstname.errors.pattern && firstname.touched">Pattern not matching</span>
</div>
在组件中,为所有窗体控件添加吸气剂。
get firstName(){
this.signUpForm.get('firstName')
}
如果您不想编写吸气剂,则可以在模板中进行更改,例如
<span *ngIf="signupForm.get('firstname').errors.required && signupForm.get('firstname').touched">This field is required</span>
替换为脏污,仅在单击时显示错误(输入模糊)。
就提交而言,如果表单无效,则不允许用户提交表单(因为角度每次更改值后都会运行所有验证器),例如禁用按钮
<button [disabled]="signupForm.invalid">Submit form</button>