Javascript 角度反应式单选按钮验证器

Javascript 角度反应式单选按钮验证器,javascript,angular,typescript,angular-reactive-forms,Javascript,Angular,Typescript,Angular Reactive Forms,我有一个带有一些单选按钮的反应式表单,如果没有选择另一个按钮,我想让其中一个按钮成为必需的 template.html <div class="delivery-container"> <form [formGroup]="deliveryForm"> <mat-radio-group aria-label="Select delivery method" formCon

我有一个带有一些单选按钮的反应式表单,如果没有选择另一个按钮,我想让其中一个按钮成为必需的

template.html

<div class="delivery-container">
  <form [formGroup]="deliveryForm">
    <mat-radio-group
      aria-label="Select delivery method"
      formControlName="deliveryMethods"
    >
      <mat-radio-button
        class="delivery-container__delivery-method"
        [value]="delivery"
        [checked]="delivery.checked"
        name="delivery.name"
        *ngFor="let delivery of deliveryMethods"
        formControlName="deliveryMethods"
        >{{ delivery.label }}
      </mat-radio-button>
    </mat-radio-group>
    <div>
      <ng-container *ngIf="!shouldDisplayPersonalPickupOptions()">
        <mat-form-field>
          <mat-label>Select delivery Country</mat-label>
          <mat-select formControlName="deliveryCountry">
            <mat-option
              [value]="delivery"
              *ngFor="let delivery of nonPersonalDeliveries"
            >
              {{ delivery.description }}
            </mat-option>
          </mat-select>
        </mat-form-field>
      </ng-container>
    </div>
    <ng-container *ngIf="shouldDisplayPersonalPickupOptions()">
      <mat-radio-group
        aria-label="Select personal pickup"
        formControlName="personalDeliveryAddress"
        class="personal-pickup-container"
      >
        <mat-radio-button
          class="personal-pickup-container__personal-method"
          *ngFor="let delivery of personalDeliveries"
          [value]="delivery.description"
        >
          <span> {{ delivery.description }}</span>
          <div>Delivery cost: {{ delivery.price }}</div>
        </mat-radio-button>
      </mat-radio-group>
      <p>Selected personal pickup: {{ selectedPersonalPickup }}</p>
    </ng-container>
  </form>
</div>
<span>{{ deliveryForm.value | json }}</span>
<span>Form is valid: {{ deliveryForm.valid }}</span>
<p>Country: {{ selectedCountry | json }}</p>
<!-- <p>{{nonPersonalDeliveries | json}}</p> -->

我的设想是:

  • 预选为“个人拾取”
  • 显示两个带有个人拾取地址的单选按钮
    • 应该选择其中一个使整个deliveryForm有效->该部分不工作,并且即使选中了这两个无线BTN中的任何一个,表单也被标记为有效
  • 如果选择了交货选项
    • 显示带有其他地址的下拉列表->在选择一个选项之前,表单应无效
    因此,只有在选择了个人地址或从下拉列表中发送时,表单才有效

    正在尝试为personalDeliveryAddress设置验证器,但无效

      observeDeliveryForm() {
        const personalDeliveryAddressControl = this.deliveryForm.get(
          'personalDeliveryAddress'
        );
        const deliveryCountryControl = this.deliveryForm.get('deliveryCountry');
        const deliveryMethodsControl = this.deliveryForm.get('deliveryMethods');
        this.deliveryForm.valueChanges
          .pipe(takeUntil(this.destroySubject))
          .subscribe((data) => {
            this.selectedDelivery = data.deliveryMethods;
            this.selectedCountry = data.deliveryCountry;
            if (this.selectedDelivery.id === 1) {
              personalDeliveryAddressControl.setValidators([Validators.required]);
              deliveryCountryControl.setValidators(null);
            }
          });
      }
    
    
      observeDeliveryForm() {
        const personalDeliveryAddressControl = this.deliveryForm.get(
          'personalDeliveryAddress'
        );
        const deliveryCountryControl = this.deliveryForm.get('deliveryCountry');
        const deliveryMethodsControl = this.deliveryForm.get('deliveryMethods');
        this.deliveryForm.valueChanges
          .pipe(takeUntil(this.destroySubject))
          .subscribe((data) => {
            this.selectedDelivery = data.deliveryMethods;
            this.selectedCountry = data.deliveryCountry;
            if (this.selectedDelivery.id === 1) {
              personalDeliveryAddressControl.setValidators([Validators.required]);
              deliveryCountryControl.setValidators(null);
            }
          });
      }