如果组中的控件之一有价值,如何以Angular 2形式进行简单的跨字段验证以通过验证?

How to do simple cross field validation in Angular 2 form to pass validation if one of the control in group has value?

这是如此常用,必须有一种简单的方法来解决这个问题!情况就是这样。我有一个表单组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  <ion-item-group formGroupName="alternativeRevenue">
    <ion-item-divider color="primary" text-wrap sticky>Alternative revenue </ion-item-divider>
    <ion-item>
      <ion-label>Branded content</ion-label>
      <ion-toggle formControlName="brandedContent"></ion-toggle>
    </ion-item>
    <ion-item text-wrap *ngIf="businessFoundationsForm.get('alternativeRevenue.brandedContent').value">
      <ion-label floating>you want to work with?</ion-label>
      <ion-input formControlName="typesOfBrands"></ion-input>
    </ion-item>
    <ion-item>
      <ion-label>Merchandise</ion-label>
      <ion-toggle formControlName="merchandise"></ion-toggle>
    </ion-item>
    <ion-item text-wrap *ngIf="businessFoundationsForm.get('alternativeRevenue.merchandise').value">
      <ion-label floating>What types of brands</ion-label>
      <ion-input formControlName="typeOfMerchandise"></ion-input>
    </ion-item>
    <ion-item>
      <ion-label>Podcasts</ion-label>
      <ion-toggle formControlName="podcasts"></ion-toggle>
    </ion-item>
    <ion-item text-wrap *ngIf="businessFoundationsForm.get('alternativeRevenue.podcasts').value">
      <ion-label floating>Brainstorm topic ideas </ion-label>
      <ion-textarea fz-elastic formControlName="podcastIdeas"></ion-textarea>
    </ion-item>
    <ion-item>
      <ion-label>Tours</ion-label>
      <ion-toggle formControlName="tours"></ion-toggle>
    </ion-item>
    <ion-item text-wrap *ngIf="businessFoundationsForm.get('alternativeRevenue.tours').value">
      <ion-label floating>Brainstorm tour </ion-label>
      <ion-textarea fz-elastic formControlName="tourIdeas"></ion-textarea>
    </ion-item>
    <ion-item>
      <ion-label>Deals</ion-label>
      <ion-toggle formControlName="licensingDeals"></ion-toggle>
    </ion-item>
    <ion-item text-wrap *ngIf="businessFoundationsForm.get('alternativeRevenue.licensingDeals').value">
      <ion-label floating>Two ideas for licensing</ion-label>
      <ion-textarea fz-elastic formControlName="licensingIdeas"></ion-textarea>
    </ion-item>
  </ion-item-group>

这是组件中的Form组:

1
2
3
4
5
6
7
8
9
10
11
12
   alternativeRevenue: this.fb.group({
    brandedContent: [false],
    typesOfBrands: [null],
    merchandise: [false],
    typeOfMerchandise: [null],
    podcasts: [false],
    podcastIdeas: [null],
    tours: [false],
    tourIdeas: [null],
    licensingDeals: [false],
    licensingIdeas: [null]
  }, {validator: alternativeRevenueGroupValidator})

我的目标是,如果select / ion-toggle之一为true,并且关联的输入字段不为空且最小长度大于10,则对from组进行验证。如果将[Validators.required,Validators.minLength(10)]添加到所有字段,它将要求在验证表单组之前填写所有字段。我只希望其中一个可以通过验证,然后整个团队都可以通过验证。我怎样才能做到这一点?

更新:这是AlternativeRevenueGroupValidator。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        function alternativeRevenueGroupValidator(c: AbstractControl) {
          let brandedContent = c.get('brandedContent');
          let typesOfBrands = c.get('typesOfBrands');
          let merchandise = c.get('merchandise');
          let typeOfMerchandise = c.get('typeOfMerchandise');
          let podcasts = c.get('podcasts');
          let podcastIdeas = c.get('podcastIdeas');
          let tours = c.get('tours');
          let tourIdeas = c.get('tourIdeas');
          let licensingDeals = c.get('licensingDeals');
          let licensingIdeas = c.get('licensingIdeas');

          if (brandedContent || merchandise || podcasts|| tours || licensingDeals) {
            if (typesOfBrands.value || typeOfMerchandise.value || podcastIdeas.value || tourIdeas.value || licensingIdeas.value) {
              return null;
            }
          }

          return {'GroupNoValue': true};
        }

您看到它非常丑陋。并且它只能验证输入字段是否有值。我无法确定最小或最大长度,也不能使用像这样的库在此处输入链接描述


FormGroup构造函数的第二个参数使您可以定义自定义组验证器。

在组验证器中,确定是否满足有效表格的条件(即,至少一个输入字段为非空,且字段长度大于10)。如果该表格有效,请通过调用control.setErrors(null)清除单个错误。否则,返回一个自定义错误对象:{ 'atLeastOneInputFieldMustBeValid': true },以便以后可以绑定到它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    function alternativeRevenueGroupValidator(c: FormGroup) {
      let brandedContent = c.get('brandedContent');
      let typesOfBrands = c.get('typesOfBrands');
      let merchandise = c.get('merchandise');
      let typeOfMerchandise = c.get('typeOfMerchandise');
      let podcasts = c.get('podcasts');
      let podcastIdeas = c.get('podcastIdeas');
      let tours = c.get('tours');
      let tourIdeas = c.get('tourIdeas');
      let licensingDeals = c.get('licensingDeals');
      let licensingIdeas = c.get('licensingIdeas');

      if (brandedContent.valid ||
          merchandise.valid ||
          podcasts.valid ||
          tours.valid ||
          licensingDeals.valid ||
          typesOfBrands.valid ||
          typesOfMerchandise.valid ||
          postcastIdeas.valid ||
          tourIdeas.valid ||
          licensingIdeas.valid) {

          brandedContent.setErrors(null);
          merchandise.setErrors(null);
          podcasts.setErrors(null);
          tours.setErrors(null);
          licensingDeals.setErrors(null);
          typesOfBrands.setErrors(null);
          typesOfMerchandise.setErrors(null);
          postcastIdeas.setErrors(null);
          tourIdeas.setErrors(null);
          licensingIdeas.setErrors(null);
          return null;
        }
      }

      return {'GroupNoValue': true};
    }

在组验证器功能内,您可以灵活地检查组内任何控件的验证标志,设置任何控件的错误对象,最后可以返回带有任意数量的验证标志的任何验证对象设置。

如果您至少需要两个字段并且大于10个字符,则可以执行以下操作:

1
2
3
4
5
6
7
8
function alternativeRevenueGroupValidator(c: FormGroup) {
      var validCtls = c.controls.filter(c=> c.valid);
      if (validCtls.length >= 2) {
           c.controls.forEach((t)=> t.setErrors(null));
           return null;
      }
      return {'GroupNoTwoValues': true};
}