Angular 2 个反应式表单字段 enable/disable

Angular 2 reactive forms field enable/disable

我正在尝试创建一个简单的 angular 2 反应形式 与电子邮件和 phone 号码。下面是我的代码。我在这里面临两个问题。

  1. 最初验证按钮应该被禁用。它应该被启用,只有 当输入电子邮件字段时。

  2. 第二个问题是我想一次只启用一个字段。如果 用户开始输入电子邮件,然后 phone 号码应该被禁用,反之亦然。如果输入电子邮件或 phone 否

  3. ,将启用保存按钮

如何实现?

<form [formGroup]="personalDtlsForm">
  <div class="form-group" [ngClass]="displayFieldCss('inputValue')">
    <div class="row">
      <div class="col">
        <label for="inputValue" class="control-label required">Email</label>
      </div>
    </div>
    <div class="row">
      <div class="col-9">
        <input type="text" id="email" class="form-control" formControlName="inputValue">
      </div>
      <div class="col-3">
        <button type="button" id="verifyBtn" class="btn btn-primary btn-large" (click)="verify()">Verify</button>
      </div>
    </div>

  </div>

  <div class="form-group row" [ngClass]="displayFieldCss('phoneNo')">
    <div class="col paddingTop">
      <label for="phoneNo" class="userID control-label textColor">Phone
      </label>
      <input type="number" class="form-control" id="phoneNo" formControlName="phoneNo">
    </div>
  </div>
  <div class="viewdetailbtn">
    <button type="button" [disabled]="!personalDtlsForm.valid" class="btn btn-primary btn-large btnwidth marginBottom" (click)="savePersonalDtls()">Save</button>
  </div>
</form>


this.personalDtlsForm = this.formBuilder.group({
  inputValue: [null, [Validators.required, Validators.email]],
      phoneNo: [null, Validators.required]
});

您可以使用 Angular FormContol 属性,例如

  • 感动
  • 未受影响
  • 错误

做到这一点。

您需要做的是检查 formControl 的状态并根据您的要求禁用字段或按钮。

Initially verify button should be disable. It should be enabled , only when email field is entered.

您可以简单地将 disabledemail 字段的有效状态绑定。提到当输入的状态被禁用时,它不会是 validinvalid.

<button type="button" [disabled]="personalDtlsForm.get('inputValue').invalid">Verify</button>

Second issue is I want to have only one field enabled at time. If user starts typing in email, then phone number should be disabled and vice versa.

为了禁用表单中的所有其他表单控件,首先我们需要访问所有这些控件,我们可以通过 formGroupDirective.directives.
我创建了一个自定义指令来实现你想要的。

@Directive({
  selector: '[disableAllOthers]'
})
export class DisableAllOthers {
  constructor(
    private elem: ElementRef, 
    private control: NgControl,
    private renderer: Renderer2
  ) {
    this.elem.nativeElement.addEventListener('mouseover', () => {
      (this.control as FormControlName).formDirective.directives.forEach(elem => {
        if (elem === this.control) {
          elem.control.enable();
        } else {
          elem.control.disable();
        }
      });
    });
  }
}

因为 click/focus 事件在禁用输入时不会触发,这里我通过 鼠标悬停 事件更改了 disable/enable,参见 demo

您可以 enable/disable 控件:

this.personalDtlsForm.controls['phoneNo'].enable()

this.personalDtlsForm.controls['phoneNo'].disable()

因此,要禁用一个字段,您必须订阅另一个字段的 valueChanges 并在 value !== '' 或类似的情况下禁用另一个字段。

示例:

this.personalDtlsForm.controls['phoneNo'].valueChanges.subscribe(
    value => {
        if(value !== ''){
            this.personalDtlsForm.controls['inputValue'].disable();
        } else {
            this.personalDtlsForm.controls['inputValue'].enable();
        }
    }
);

当然还有 inputValue formControl

上的同种订阅

对于你的第二个问题,你可以在value !== ''时的if语句中设置一个变量isFormValid,这意味着至少输入了其中一个。

启用按钮的最终检查可能类似于:

isFormValid && personalDtlsForm.valid

如果您使用反应式表单方法从用户那里获取输入,然后您希望根据用户操作启用或禁用这些字段。因此,您可以执行以下操作...

假设您的 FormGroup 如下所示 -->

// cityRef field will be automatically disabled intially, as property disabled: true is set

this.signUpFrom = new FormGroup({
      userData: new FormGroup({
        mobileNumber: new FormControl(null, [Validators.required, Validators.minLength(10), Validators.maxLength(10)]),
        password: new FormControl(null, [Validators.required]),
        userType: new FormControl('VENDOR')
      }),
      otherData: new FormGroup({
        cityRef: new FormControl({ value: null, disabled: true }, [Validators.required]),
        email: new FormControl(null, [Validators.required, Validators.email]),
        address: new FormControl(null, [Validators.required])
      }),
      name: new FormControl(null, [Validators.required]),
    });

现在,如果您想根据用户操作禁用/启用电子邮件、密码、姓名等。 您只需一步即可完成此操作。 (访问不同字段的示例)

this.signUpFrom.get('otherData.email').enable(); // To enable
this.signUpFrom.get('otherData.email').disable(); // To disable

this.signUpFrom.get('userData.password').enable(); // To enable
this.signUpFrom.get('userData.password').disable(); // To disable

this.signUpFrom.get('name').enable(); // To enable name field
this.signUpFrom.get('name').disable(); // To disable name field

你可以把这些代码放到onClick或者onChanges等可以调用的函数中

即使您可以通过使用

了解禁用或启用字段天气的当前情况
this.signUpFrom.get('name').disabled; // return true if disabled
this.signUpFrom.get('name').enabled; // return true if enabled

可能会迟到回答这个问题,但由于我发现它很有用,所以我想回答它,因为这可能对您或其他人有帮助!