在反应式表单中,我如何创建一个自定义验证器,该验证器可以验证没有值的 formGroup 数组?

问题描述

我的意思是我有一个包含动态订单商品集合的订单页面。我想要求用户在该数组中至少有一项。我了解自定义验证器的简单用法,但在这种情况下,我不是验证单个控件而是验证数组。我怎么说“如果数组中没有值则给出错误”?

createFormGroup(order: Order): FormGroup {
const group = this.fb.group({
  id: [order.id],isItPurchase: [order.isItPurchase],orderItems: this.fb.array([])
});

order.orderItems.forEach(x => {
  var formArray = group.controls.orderItems as FormArray;
  formArray.push(this.createOrderItem(x));
});

    return group;
  }

 
 createOrderItem(item: OrderItem): FormGroup {
    const formGroup = this.fb.group({
      id: [item.id],name: [item.name,Validators.required],unitPrice: [item.unitPrice,units: [item.units,Validators.required]
    });

    return formGroup;
  }

对于一个简单的案例,我会做类似的事情

      // xxxValidator(control: AbstractControl): { [key: string]: boolean } | null {
  //   if (control.value === 'xxx') {
  //     return { 'xxxValidator': true }
  //   }
  //   return null;
  // };

编辑 1:

我离得更近了。我确定错误何时存在。但是我的模板是错误的。如何查看模板中的错误

createFormGroup(order: Order): FormGroup {
    const group = this.fb.group({
      id: [order.id],orderItems: this.fb.array([])
    },{ validators: [this.testValidation1] }
      // { validators: [this.testValidation2] }
    );

    order.orderItems.forEach(x => {
      var formArray = group.controls.orderItems as FormArray;
      formArray.push(this.createOrderItem(x));
    });

    return group;
  }

  createOrderItem(item: OrderItem): FormGroup {
    const formGroup = this.fb.group({
      id: [item.id],Validators.required]
    });

    return formGroup;
  }

  testValidation1(form: FormGroup) {
    if (form.value.orderItems.length === 0) {
      return { valOrderItems: false };
    }

    return null;
  }

    <div>
        <div *ngFor="let fg of orderItems.controls;  let i=index">
            <app-order-item-form [orderItemForm]="fg" (itemDeleted)="onItemDeleted(i)"></app-order-item-form>
        </div>
        <!-- <span *ngIf="orderForm.errors.valOrderItems"> Must be atleast one orderItem </span> -->
    </div>

解决方法

也许你应该得到 FormArray 控件

   get itemsFormArray(): FormArray {
        return this.createFormGroup.get('orderItems') as FormArray;
    }

然后在您的模板中使用它,也许它不起作用或不是您需要的,但我希望它能给您提供线索

  <mat-error *ngIf="itemsFormArray.hasError('required')">
                    // ERROR MESSAGE               
  </mat-error>
,

选项 1

您可以使用 required 验证器来验证表单是否至少包含一个元素


const group = this.fb.group({
  id: [order.id],isItPurchase: [order.isItPurchase],orderItems: this.fb.array([],[Validators.required])
});

现在获取如果数组没有值,您可以检查 required 验证器是否失败

const error = group.get('orderItems').hasError('required');  // True if form is empty

选项 2

创建验证器函数

function formIsEmpty(control: FormArray) {
  if (control.controls.length === 0) {
    return { noValue: true}
  }
  return null;
}

在您的 FormGroup 中,您可以像使用它一样


const group = this.fb.group({
  id: [order.id],[formIsEmpty])
});

并得到错误

group.get('orderItems').hasError('noValue');

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...