У меня есть компонент сводки проверки, как показано ниже:
Компонент ниже извлекает ngform, но не может подписаться на statuschanges / Valuechanges и отобразить сводку сообщения об ошибке.
export class ValidationSummaryComponent implements OnInit {
@Input() form: NgForm;
errors: string[] = [];
constructor() { }
ngOnInit() {
if (this.form instanceof NgForm === false) {
throw new Error('You must supply the validation summary with an NgForm.');
}
this.form.statusChanges.subscribe(status => {
this.resetErrorMessages();
this.generateErrorMessages(this.form.control);
});
}
resetErrorMessages() {
this.errors.length = 0;
}
generateErrorMessages(formGroup: FormGroup) {
Object.keys(formGroup.controls).forEach(controlName => {
const control = formGroup.controls[controlName];
console.info('control.......... ', control);
const errors = control.errors;
console.info('control.errors.......... ', control.errors);
if (errors === null || errors.count === 0) {
return;
}
// Handle the 'required' case
if (errors.required) {
this.errors.push(`${controlName} is required`);
}
// Handle 'minlength' case
if (errors.minlength) {
this.errors.push(`${controlName} minimum length is ${errors.minlength.requiredLength}.`);
}
// Handle custom messages.
if (errors.message) {
this.errors.push(`${controlName} ${errors.message}`);
}
});
} }
и validation-summary.component.html
<div *ngIf = "errors?.length > 0" class = "validation-summary">
<p>Please fix the following errors:</p>
<ul>
<li *ngFor = "let error of errors">{{ error }}</li>
</ul>
dynamic-form.component.ts
constructor(public formBuilder: FormBuilder) {
}
productFormGroup: FormArray;
ngOnInit() {
this.productFormGroup = this.formBuilder.array([]);
this.ProductList.forEach(product => {
this.productFormGroup.push(this.formBuilder.group({
productId: [product.productId],
displayName: [product.displayName],
productName: [product.productName, Validators.required]
}));
});
} }
dynamic-form.component.html, использующий сводку проверки.
<div id = "mainWrapper">
<app-validation-summary-component [form] = "userForm"></app-validation-summary-component>
<form #userForm = "ngForm">
<div [formGroup] = "product" *ngFor = "let product of
productFormGroup.controls>
<label>{{product.get('displayName').value}}</label>
<input class = "form-control"
name = "product.get('displayName').value"
formControlName = "productName" required/>
</div>
<button class = "btn btn-primary" type = "submit"
[disabled] = "!productFormGroup.valid">Submit </button>
<button class = "btn btn-primary" style = "margin-left: 30px" type = "reset"
(click) = "reset()"> Reset </button>
</form>
</div>
Необходимо отображать сводку сообщений об ошибках поверх компонента динамической формы, отображающего список имен меток, который является пустым / недействительным.
функция resetErrorMessages () должна быть {this.errors=[]}
, вы не можете изменить "длину массива", вы должны изменить массив
То, как вы зацикливаете элемент управления formarray formgroup, не является правильным внутри validation-summary.component. Созданный stackblitz объясняет решение.
https://stackblitz.com/edit/angular-mr49zh
Большое спасибо, Суреш! это именно то, что я хотел .... но при отображении сообщения об ошибке он выберет то же имя, что и «требуется отображаемое имя», вместо этого он должен выбрать уникальное значение и сказать, что требуется angular. Или React требуется, пожалуйста, обратитесь к руководству.
Вы должны использовать «отображаемое имя». так полезно для других.
Я проголосовал за, потому что у меня только 3 репутации :(, я действительно хочу отображать сообщения об ошибках, такие как angular, в настоящее время требуется отображение отображаемого имени для всех 3 полей, если в нем есть ошибки, вместо этого он должен исправить уникальное имя для каждого поля и говорят, что требуется angular или требуется реакция ....
я думаю, что нашел решение с приведенным ниже фрагментом кода .... if (formInnerControl && (_formControl.status === 'INVALID' || formInnerControl.errors) && formElement === 'displayName') {me.errors.push (formInnerControl.value + is required
); } надеюсь, что это поможет другим ....
Вот группа функций, которая перебирает все элементы FromControl в FormGroup, включая вложенные элементы FormControl в FormArray и создание сводки проверки.
getFormSummaryHtml(formGroup, fg_discription){
let allErrors = this.getFormSummary(formGroup, '');
let error_obj = this.setErrorFormat(allErrors, fg_discription)
if (error_obj){
let html = this.getHtmlFromObject(error_obj, '')
return html;
}
}
getHtmlFromObject(error_obj, html) {
if (error_obj.value) {
for (let index = 0; index < error_obj.value.length; index++) {
const element = error_obj.value[index];
html += `<ul> <li>`;
html += element.text;
if (element.value) {
html = this.getHtmlFromObject(element.value, html)
}
html += ` </li> </ul>`;
}
}
else if (error_obj.length > 0) {
html += `<ul>`;
for (let index = 0; index < error_obj.length; index++) {
const element = error_obj[index];
html += element.text;
if (element.value) {
html = this.getHtmlFromObject(element.value, html)
}
else {
// to Remove last appended text
html = html.substring(0, html.length - element.text.length);
html += `<li> ${element.text} </li>`
}
}
html += `</ul>`;
}
else {
html += error_obj.text;
}
return html
}
getFormSummary(formGroup, parentGroup) {
let errors = []
for (const key in formGroup) {
if (Object.prototype.hasOwnProperty.call(formGroup, key)) {
const element = formGroup[key];
if (element instanceof FormGroup) {
parentGroup = parentGroup == '' ? key : parentGroup + '>' + key;
let terror = this.getFormSummary(element.controls, parentGroup)
errors = [...errors, ...terror]
}
if (element instanceof FormArray) {
parentGroup = parentGroup == '' ? key : parentGroup + '>' + key;
for (let index = 0; index < element.controls.length; index++) {
let ele = element.controls[index];
let terror = this.getFormSummary(ele["controls"], parentGroup)
errors = [...errors, ...terror]
}
}
if (element instanceof FormControl && element.valid == false && element.errors && Object.keys(element.errors).length > 0) {
for (const errorTypes in element.errors) {
errors.push(parentGroup + '>' + key + ':' + errorTypes)
}
}
}
}
return errors;
}
setErrorFormat(errors,discription){
let errorObj: { text: string, key: string, value: Array<any>};
for (let index = 0; index < errors.length; index++) {
let element = errors[index];
let elements = element.split(':');
let error_elements = elements[0].split('>')
error_elements.forEach((ele,idx) => {
if (errorObj == null){
errorObj = { text: discription[ele], key: ele, value: null };
}
else if (idx > 0){
let error_t_obj = this.getErrorElement(errorObj, ele);
let error_ele_obj = this.getErrorElement(errorObj, error_elements[idx - 1]);
if (error_ele_obj && (error_t_obj == null || error_t_obj.key != error_elements[idx])) {
let obj = { text: discription[ele], key: ele, value: null };
error_ele_obj.value = error_ele_obj.value && error_ele_obj.value.length > 0 ? error_ele_obj.value : new Array();
error_ele_obj.value.push(obj)
}
}
});
}
return errorObj;
}
getErrorElement(error,s_key){
if (error.key == s_key) {
return error;
}
else if (error.value && error.value.length > 0) {
for (let index = 0; index < error.value.length; index++) {
let ele = error.value[index];
let objerror = this.getErrorElement(ele, s_key);
if (objerror != null ){
return objerror;
}
}
}
}
Как это назвать?
getFormSummary(){
// This array contains FromControls name and Names of controls that user can understand
let fg_discription = {
saleGroup: "Sales",
sale_date: "Sale date",
sale_type_id: "Sale type",
deal_type_id: "Deal type",
lender_id: "Lender",
wholesaler_id: "Wholesaler",
published_price: "Published price",
pack: "Pack",
allowance: "Allowance"
};
let html = this.getFormSummaryHtml(this.addSalesForm.controls, fg_discription)
return html;
}
validateFormOnSubmission() {
let form = this.addSalesForm.value;
let html = this.getFormSummary()
if (html == undefined) {
// Submit Form
this.onSubmitAddSales();
}
else { // Show Html in POP message
this.popMessage({ detail: "Following fields are mandatory: ", data: { html }, key: "popup" })
}
}
попытайтесь отобразить ошибки "более угловым способом": не создавайте текст с .html, иначе используйте *ngFor
непосредственно в .html
Если вы хотите объект и отображать его с помощью ngFor, тогда let error_obj = this.setErrorFormat(allErrors, fg_discription)
имеет объект ошибки.
вы можете использовать что-то вроде flash в узле, в зависимости от платформы, которую вы используете на стороне сервера.