angular 添加不可禁用的表单

9udxz4iz  于 2022-10-29  发布在  Angular
关注(0)|答案(1)|浏览(290)

哪些@angular/* 包与功能请求相关?

表格

描述

对于angular 14,我一直在使用新的类型化形式,我通常发现令人恼火的是值的类型总是Partial,举这个简单的例子

// login.component.ts

loginForm = this.formBuilder.nonNullable.group({
  username: ['', [Validators.required]],
  password: ['', [Validators.required]],
});

如果我尝试将this.loginForm.value传递给一个具有如下接口的方法

export interface User {
  username: string;
  password: string;
}

它将失败,并显示以下错误

Error: src/app/login/login.component.ts:33:28 - error TS2345: Argument of type 'Partial<{ username: string; password?: string | undefined; }>' is not assignable to parameter of type 'User'.
  Types of property 'username' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.

33     this.userService.login(this.loginForm.value);
                              ~~~~~~~~~~~~~~~~~~~~~

我理解这是因为我们可以禁用一个formControl,而这将使这个控件不在value
并且我知道this.loginForm.getRawValue()将在没有Partial的情况下给予值,但这不能防止禁用formControl

建议的解决方案

它将与FormBuildernonNullable类似,并且在FormControl的选项内部
我们添加了nonDisableable,当给定它时,用户不能禁用表单控件(类似于我们现在的removeControl
这应该做两件事
1.如果我们将其用于formBuilder,则表单的值将是没有我们今天所拥有的部分的值,并且所有控件都将满足所需的
1.如果我们将它用于某些formControl,则这些控件将被标记为必需,而只有其他控件将被标记为可选

考虑的替代方案

我们可以将removeControl和disableable组合在一起
当前默认情况下,您不能删除控件,除非标记为可选
类似地,除非标记为可选,否则禁止禁用它们
例如,在上面的例子中,你可以执行this.loginForm.disable();来禁用所有控件,或者执行this.loginForm.controls.username.disable();来只禁用username
但不允许执行this.loginForm.removeControl('username');来删除用户名
但我们可以更改它,使其不允许执行removeControldisable,除非此控件标记为可选
在我看来,第一个建议更好,因为您可以将formControl标记为disableable但不可删除,这是不同的,因为即使它被禁用,this.loginForm.controls.username仍将始终是FormControl,而将其标记为removable将使其成为FormControl | undefined

mrfwxfqh

mrfwxfqh1#

如果该建议被接受,我们需要考虑将该警告设置为错误

It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true
  when you set up this control in your component class, the disabled attribute will actually be set in the DOM for
  you. We recommend using this approach to avoid 'changed after checked' errors.

  Example:
  // Specify the `disabled` property at control creation time:
  form = new FormGroup({
    first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
    last: new FormControl('Drew', Validators.required)
  });

  // Controls can also be enabled/disabled after creation:
  form.get('first')?.enable();
  form.get('last')?.disable();

相关问题