Angular - 如何根据可见的 div 元素进行验证

Angular - How to validate based on the visible div element

在我的 Angular-13 中,我想 Show/Hide div 元素使用 ng-select 下拉列表。我有这个代码:

枚举

export const CHARGE_REQUIRED_DATA = [
  {
    'key': 0,
    'value': 'False'
  },
  {
    'key': 1,
    'value': 'True'
  }
]

export const CHARGE_MODE_DATA = [
  {
    'key': 1,
    'value': 'Fixed'
  },
  {
    'key': 2,
    'value': 'Percentage'
  }
]

然后在组件中,我有这样的代码:

component.ts

import { CHARGE_MODE_DATA } from 'src/app/core/enum/chargemode';
import { CHARGE_REQUIRED_DATA } from 'src/app/core/enum/chargerequired';

export class TransCreateComponent implements OnInit {

  createTransForm!: FormGroup;
  selectedChargeRequired:any;
  selectedChargeMode:any;

  constructor(
    private fb: FormBuilder,
    ) { }

  ngOnInit(): void {
    this.createTrans();
    this.chargeRequiredData = CHARGE_REQUIRED_DATA;
    this.chargeModeData = CHARGE_MODE_DATA;
  }

  createTrans() {
    this.createTransForm = this.fb.group({
      ChargeRequired: ['', [Validators.required]],
      ChargeMode: [''],
      ChargePercent: ['', RxwebValidators.numeric({allowDecimal:true,isFormat:true})],
      ChargeValue: ['', RxwebValidators.numeric({allowDecimal:true,isFormat:true})],
    });
  }

component.html:

  <div class="col-md-4">
    <div class="form-group">
      <label for="ChargeRequired">Charges Required<span style="color:red;">*</span></label>
      <ng-select [items]="chargeRequiredData"
        [selectOnTab]="true"
        [searchable]="true"
        bindValue="key"
        bindLabel="value"
        placeholder="Select Charge Required"
        [multiple]="false"
        [clearable]="true"
        [(ngModel)]="selectedChargeRequired"
        formControlName="ChargeRequired">
      </ng-select>
      <div *ngIf="fc['ChargeRequired'].touched && fc['ChargeRequired'].invalid" class="alert alert-danger">
        <div *ngIf="fc['ChargeRequired'].errors && fc['ChargeRequired'].errors['required']">The field is required!</div>
      </div>
    </div>
  </div>

  <ng-container *ngIf="selectedChargeRequired == '1'">
    <div class="col-md-4">
      <div class="form-group">
        <label for="ChargeRequired">Charge Mode</label>
        <ng-select [items]="chargeModeData"
          [selectOnTab]="true"
          [searchable]="true"
          bindValue="key"
          bindLabel="value"
          placeholder="Select Charge Required"
          [multiple]="false"
          [clearable]="true"
          [(ngModel)]="selectedChargeMode"
          formControlName="ChargeMode">
        </ng-select>
      </div>
    </div>
  </ng-container>

  <ng-container *ngIf="selectedChargeMode == '2'">
    <div class="col-md-4">
      <div class="form-group">
        <label for="ChargePercent">Charge Percent</label>
        <input type="text" formControlName="ChargePercent" class="form-control" id="ChargePercent" placeholder="Enter Charge Percent">
      </div>
    </div>
  </ng-container>
  <ng-container *ngIf="selectedChargeMode == '1'">
    <div class="col-md-4">
      <div class="form-group">
        <label for="ChargeValue">Charge Value</label>
        <input type="text" formControlName="ChargeValue" class="form-control" id="ChargeValue" placeholder="Enter Charge Value">
      </div>
    </div>
  </ng-container>

我正在使用 ng-select 下拉列表。

预计:

  1. On ChargeRequired select,如果 selectedChargeRequired 为 1,则 ChargeMode 应该可见。
  2. 如果 ChargeMode 是 1,ChargeValue 应该是可见的,如果是 2 那么 ChargePercent 应该是可见的。

以上逻辑有效。

如何使 ChargeMode、ChargePercent 和 ChargeValue 的验证仅在可见时才适用。 并且在可见时还应要求它们中的每一个?

谢谢

您可以在表单控件上有条件地设置所需的验证器,也可以将其清除。请参阅此示例。

在 oninit 内部订阅,首先在您的 formcontrol 上订阅观察变化。

 this.createTransForm.get('ChargeRequired').valueChanges
                     .subscribe(value => this.toggleValidity(value));

然后定义toggleValidity方法来应用或取消验证

toggleValidity(selectedChargeRequired : string): void {    
    if(selectedChargeRequired === '1') {
        const chargeModeCntrl = this.createTransForm.get('ChargeMode');    
        chargeModeCntrl.setValidators(Validators.required);
        chargeModeCntrl.updateValueAndValidity();            
    }
    else {
        this.createTransForm.controls["ChargeMode"].setErrors(null);
        this.createTransForm.controls["ChargeMode"].clearValidators();
        this.createTransForm.controls["ChargeMode"].updateValueAndValidity();
    }
}