简体   繁体   English

使用* ngIf动态构建的元素使用验证器进行角度2形式验证

[英]Angular 2 Form Validation Using Validators WIth An Element That Is Dynamically Built Using *ngIf

I have a form and am using Reactive Forms for validation. 我有一个表单,我正在使用Reactive Forms进行验证。 I can get all the validation to work EXCEPT I have some inputs that are served conditionally that are still keeping the form from validating even when they are not served to the view using *ngIf. 我可以使所有验证工作除了我有一些有条件服务的输入,即使它们没有使用* ngIf提供给视图时仍然保持表单验证。 How can I say "Validators.required" only if a condition is true. 如果条件为真,我怎么能说“Validators.required”。 Please see example. 请看例子。

constructor(
    private QRService:QRService,
    fb: FormBuilder
    ){
    this.title = 'My Form';
    this.showDeliveryTypes = false;
    this.complexForm = fb.group({
      'itemnumber' : [null, Validators.required],
      'dateofbirth' : [null, Validators.required],
      'deliverytype' : [null, Validators.required],
      'pickuplocation' : [null, Validators.required], //validates even if these aren't included using *ngIf
      'paymentoptions' : [null, Validators.required] //validates even if these aren't included using *ngIf
   })

};

I only want to validate pickuplocations or paymentoptions if the *ngIf includes them in the form. 如果* ngIf在表单中包含它们,我只想验证picklocations或paymentoptions。

<form [formGroup]="complexForm" (ngSubmit)="findScript(complexForm.Form)">
  <h2>Script Number</h2>
  <input type="number" name="script" [(ngModel)]="itemno" (blur)="getScripts(itemno)" [formControl]="complexForm.controls['itemnumber']">
  <h2>Date of birth</h2>
  <input type="date" name="dob" [(ngModel)]="dateofbirth" (blur)="getScripts(scriptno, dateofbirth)" [formControl]="complexForm.controls['dateofbirth']" required>
  <div *ngIf="showDeliveryTypes" name="deliverytypes">
  <h3>Delivery Method</h3>
  <select #select [(ngModel)]="selectedId" (change)="validateDeliveryTypes(select.value)" name="deliveryoptions" [formControl]="complexForm.controls['deliverytype']">
    <option *ngFor="let item of qrData.DeliveryTypes" [value]="item.DeliveryTypeId">{{item.DeliveryTypeName}}</option>

  </select>
  </div>
  <div *ngIf="showPickupLocations" name="pickuptypes">
  <h3>Pickup Locations</h3>  //I don't want to validate these UNLESS the *ngIf is true
  <select #select [(ngModel)]="selectedPickupId" (change)="checkVals(select.value)" name="pickupoptions" [formControl]="complexForm.controls['pickuplocation']">
    <option *ngFor="let item of selectedItem.PickupLocations" [value]="item.PickupLocationId">{{item.PickupLocationName}}</option>

  </select>
  </div>
  <div *ngIf="showPaymentOptions" name="paymentoptions">
  <h3>Payment Types</h3>  //I don't want to validate these UNLESS the *ngIf is true
  <select #select [(ngModel)]="selectedPayment" (change)="checkVals(select.value)" name="selectpaymentoptions" [formControl]="complexForm.controls['paymentoptions']">
    <option *ngFor="let item of selectedItem.PaymentTypes" [value]="item.PaymentTypeId">{{item.PaymentTypeName}}</option>

  </select>
  </div>
  <button (click)="findScript()" type="submit" name="submitbutton" [disabled]="!complexForm.valid">Find Prescription</button>
</form>

I'm still fairly new to Angular2 and can do this easily in Angular 1, but really wanting to move to Angular2 with future development. 我还是Angular2的新手,可以在Angular 1中轻松完成,但是真的想在未来的开发中转向Angular2。

One way would be to disable the form field when you are hiding it from the DOM. 一种方法是在从DOM中隐藏表单字段时禁用表单字段。 Disabling the form control, excludes that form field from the form entirely, which is what you want. 禁用表单控件,完全从表单中排除该表单字段,这是您想要的。 If you do need to get the value included in your form upon submit, you can use the method getRawValue . 如果您确实需要在提交时获取表单中包含的值,则可以使用方法getRawValue But otherwise the form fields will be excluded entirely. 但是否则表格字段将被完全排除。

Since your form is pretty complex, I have set up a simple example code and plunker for you, where we disable lastname and remove it from the DOM. 由于您的表单非常复杂,我已经为您设置了一个简单的示例代码和plunker,我们禁用lastname并将其从DOM中删除。

Since not knowing how you toggle the showPickupLocations and showPaymentOptions , I'll just use a button here, which toggles the visibility of lastname. 由于不知道你如何切换showPickupLocationsshowPaymentOptions ,我只需在这里使用一个按钮,它可以切换姓氏的可见性。 So the form would look like this: 所以表单看起来像这样:

<button (click)="toggle()">Toggle lastname</button>
<form [formGroup]="myForm">
  <label>firstname: </label>
  <input formControlName="firstname"/>
  <div *ngIf="toggl">
     <label>lastname: </label>
     <input formControlName="lastname"/>
  </div>
</form>

And when we toggle lastname visibility in DOM, we also toggle the enabling and disabling of the formfield: 当我们在DOM中切换lastname可见性时,我们还会切换表单域的启用和禁用:

toggle() {
  this.toggl = !this.toggl;
  let control = this.myForm.get('lastname')
  control.enabled ? control.disable() : control.enable()
}

As said, this excludes the field from the form, so validation will not be a problem. 如上所述,这从表单中排除了字段,因此验证不会成为问题。 In this demo plunker you can see how the toggling removes the lastname field from the form values entirely. 在这个演示plunker中,您可以看到切换如何从表单值中完全删除lastname字段。

Demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM