Angular 2 FormBuilder 根据复选框选择禁用字段

26

我已经建立了一个 Angular CLI 项目,并且有一个带有复选框的表单。其中一些字段必须在复选框选择时禁用。

表单如下:

输入图像描述

需要在复选框选择事件上禁用/启用密码、新密码和重新输入密码字段。

HTML

<form [formGroup]="userProfileForm" (ngSubmit)="submitForm(userProfileForm.value)">

    <div class="row">
        <div class="col">
            <div class="form-group">
                <label> {{ 'USER_PROFILE_MODEL.USER_NAME' | translate }}</label>
                <input class="form-control" type="text" [formControl]="userProfileForm.controls['userName']">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.DISPLAY_NAME' | translate }}</label>
                <input class="form-control" type="text" [formControl]="userProfileForm.controls['displayName']">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.EMAIL' | translate }}</label>
                <input class="form-control" type="text" [formControl]="userProfileForm.controls['email']">
            </div>
        </div>
        <div class="col">
            <div class="form-group ">
                <label class="checkbox-inline">
                <input type="checkbox" value="isResetPassword" name="isResetPassword" [formControl]="userProfileForm.controls['isResetPassword']">  
                 {{ 'USER_PROFILE_MODEL.RESET_PASSWORD' | translate }}
              </label>
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.PASSWORD' | translate }}</label>
                <input class="form-control" type="password" [formControl]="userProfileForm.controls['password']">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.NEW_PASSWORD' | translate }}</label>
                <input class="form-control" type="password" [formControl]="userProfileForm.controls['newPassword']">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.RE_TYPE_PASSWORD' | translate }}</label>
                <input class="form-control" type="password" [formControl]="userProfileForm.controls['reTypePassword']">
            </div>

        </div>

    </div>
</form>

TS代码

this.isResetPassword = true;
this.userProfileForm = formBuilder.group({
    'userName': [null, [Validators.required]],
    'displayName': [null],
    'email': [null, [Validators.required]],
    'isResetPassword': this.isResetPassword,
    'password': [{
        value: null,
        disabled: this.isResetPassword
    }],
    'newPassword': [{
        value: null,
        disabled: this.isResetPassword
    }],
    'reTypePassword': [{
        value: null,
        disabled: this.isResetPassword
    }]
})
构造函数中已经创建了表单。 如何在选择复选框时禁用/启用上述字段。
Translated:

构造函数中已经创建了表单。如何在选择复选框时禁用/启用上述字段。


根据上述答案,使用formControlName。在复选框的点击事件中调用一个事件处理程序,在其中切换isResetPassword的值,然后添加以下语句。 userProfileForm.updateValueAndValidity(); - Prathmesh Dali
5个回答

50

起初,我认为您想要在选中重置密码复选框 isResetPassword 时才启用特定字段,是吗?如果是这样的话,请看以下步骤:

1 - 表单的构建应该像这样:

this.userProfileForm = this.formBuilder.group({
  // ...
  password: [{
    value: null,
    disabled: !this.isResetPassword
  }],
  newPassword: [{
    value: null,
    disabled: !this.isResetPassword
  }],
  reTypePassword: [{
    value: null,
    disabled: !this.isResetPassword
  }]
});

请注意,这里只在this.isResetPassword为false时禁用输入。

2 - 要检测<input type="checkbox">的变化,您可以在模板中使用(change)

<label>
  <input 
    type="checkbox" 
    [formControl]="userProfileForm.controls['isResetPassword']" 
    (change)="handleChange($event)">
  {{ 'USER_PROFILE_MODEL.RESET_PASSWORD' | translate }}
</label>

... 或者甚至在组件中,使用valueChanges

this.userProfileForm.get('isResetPassword').valueChanges.subscribe(value => this.handleChange(value));

当然啦,这里是用来操作字段状态的function

handleChange(value: boolean): void {
  const passwordCtrl = this.userProfileForm.get('password');
  const newPasswordCtrl = this.userProfileForm.get('newPassword');
  const reTypePasswordCtrl = this.userProfileForm.get('reTypePassword');

  if (value) {
    passwordCtrl.enable();
    newPasswordCtrl.enable();
    reTypePasswordCtrl.enable();
  } else {
    passwordCtrl.disable();
    newPasswordCtrl.disable();
    reTypePasswordCtrl.disable();
  }
}

一些提示:

1-虽然这只是个人偏好,但值得提到的是,您不需要像这样使用[formControl]:

[formControl]="userProfileForm.controls['isResetPassword']"

相反,您可以直接使用 formControlName

formControlName="isResetPassword"
注意,你可以对所有的控件执行相同的操作。
2 - 由于已经在表单中引用了userProfileForm,所以在ngSubmit中不需要传递表单值。
替代方法:
(ngSubmit)="submitForm(userProfileForm.value)"

submitForm(value: any) { console.log(value); }

这个:

(ngSubmit)="submitForm()"

submitForm() { console.log(this.userProfileForm.value); }

3- 如果您想查看禁用输入的value值,而不是使用.value,您应该使用.getRawValue(),像这样:

this.userProfileForm.getRawValue();

此处是DEMO(使用(change)

此处是DEMO(使用valueChanges


6
最简单的方法是创建一个专门用于密码的表单组:
this.userProfileForm = formBuilder.group({
  'userName': [null, [Validators.required]],
  'displayName': [null],
  'email': [null, [Validators.required]],
  password: formBuilder.group({
    'isResetPassword': this.isResetPassword,
    'password': [null],
    'newPassword': [null],
    'reTypePassword': [null]
  })
})

然后在您的模板中将密码列更改为以下内容:
<div class="col" formGroupName="password>
  <div class="form-group ">
    <label class="checkbox-inline">
      <input type="checkbox" formControlName="isResetPassword">  
      {{ 'USER_PROFILE_MODEL.RESET_PASSWORD' | translate }}
    </label>
  </div>
  <div class="form-group ">
    <label>{{ 'USER_PROFILE_MODEL.PASSWORD' | translate }}</label>
    <input class="form-control" type="password" formControlName="password" >
  </div>
  <div class="form-group ">
    <label>{{ 'USER_PROFILE_MODEL.NEW_PASSWORD' | translate }}</label>
    <input class="form-control" type="password" formControlName="newPassword">
  </div>
  <div class="form-group ">
    <label>{{ 'USER_PROFILE_MODEL.RE_TYPE_PASSWORD' | translate }}</label>
    <input class="form-control" type="password" formControlName="reTypePassword">
  </div>
</div>

在你的组件上:
//when value changes, to disable all the fields just do this
this.userProfileForm.controls.password.disable();
// to enable them back
this.userProfileForm.controls.password.enable();

4

这篇文章中的大多数方法都可以使用,但需要使用 setTimeout 进行操作:

setTimeout(() => {
    if (this.disable) {
       this.userProfileForm.controls.password.disable();
    }
    else {
        this.userProfileForm.controls.password.enable();
    }
});

看起来是一个Angular的bug,问题在这里这里


-1

不要在模板中使用[formControl]来控制表单,而是使用formControlName

你的表单应该像这样:

<form [formGroup]="userProfileForm" (ngSubmit)="submitForm(userProfileForm.value)">

    <div class="row">
        <div class="col">
            <div class="form-group">
                <label> {{ 'USER_PROFILE_MODEL.USER_NAME' | translate }}</label>
                <input class="form-control" type="text" formControlName="userName">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.DISPLAY_NAME' | translate }}</label>
                <input class="form-control" type="text" formControlName="displayName">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.EMAIL' | translate }}</label>
                <input class="form-control" type="text" formControlName="email">
            </div>
        </div>
        <div class="col">
            <div class="form-group ">
                <label class="checkbox-inline">
                <input type="checkbox" value="isResetPassword" name="isResetPassword" formControlName="isResetPassword">  
                 {{ 'USER_PROFILE_MODEL.RESET_PASSWORD' | translate }}
              </label>
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.PASSWORD' | translate }}</label>
                <input class="form-control" type="password" formControlName="password" [attr.disabled]="userProfileForm.value.isResetPassword?'':null">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.NEW_PASSWORD' | translate }}</label>
                <input class="form-control" type="password" formControlName="newPassword" [attr.disabled]="userProfileForm.value.isResetPassword?'':null">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.RE_TYPE_PASSWORD' | translate }}</label>
                <input class="form-control" type="password" formControlName="reTypePassword" [attr.disabled]="userProfileForm.value.isResetPassword?'':null">
            </div>

        </div>

    </div>
</form>

你必须像这样定义你的表单:

this.userProfileForm = formBuilder.group({
    'userName': [null, [Validators.required]],
    'displayName': [null],
    'email': [null, [Validators.required]],
    'isResetPassword': [false],
    'password': [null],
    'newPassword': [null],
    'reTypePassword': [null]
})

-3
你需要在复选框点击时编写一个回调函数,例如:(click)="checkBoxClicked()"。在组件中定义回调函数如下:
checkBoxClicked() {
 if(!this.userProfileForm.controls.isResetPassword.value) {
   this.userProfileForm.controls.password.disable();
   this.userProfileForm.controls.newPassword.disable();
   this.userProfileForm.controls.reTypePassword.disable();
 }else {
   this.userProfileForm.controls.password.enable();
   this.userProfileForm.controls.newPassword.enable();
   this.userProfileForm.controls.reTypePassword.enable();
 }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接