将FormGroup放入类的最佳方法

时间:2018-10-14 16:13:21

标签: angular typescript angular-reactive-forms

我是反应式表单的新手,我曾经使用过模板驱动的表单。

我在这里关注本教程:https://angular-templates.io/tutorials/about/angular-forms-and-validations

我有一个用户类别:

export class User {
  public pseudo: string;
  public email: string;
  public password: string;

  public constructor(init?: User) {
    Object.assign(this, init);
  }
}

然后我将FormGroups放在了一个组件中:

 this.matching_passwords_group = new FormGroup(
      {
        password: new FormControl(
          '',
          Validators.compose([
            Validators.minLength(5),
            Validators.required,
            Validators.pattern(
              '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]+$'
            )
          ])
        ),
        confirm_password: new FormControl('')
      },
      (formGroup: FormGroup) => {
        return PasswordValidator.areEqual(formGroup);
      }
    );

    // user details form validations
    this.userDetailsForm = this.fb.group({
      pseudo: new FormControl('', Validators.required),
      email: new FormControl(
        '',
        Validators.compose([
          Validators.required,
          Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$')
        ])
      ),
      matching_passwords: this.matching_passwords_group,
      terms: new FormControl(false, Validators.pattern('true'))
    });
  }

您会看到嵌套的formGroup用于密码确认(检查两个密码是否相等)。

然后,当用户单击“提交”时,我想将formGroup的值转换为我的User对象。

我遵循了这里的建议:Reactive Forms correctly convert Form Value to Model Object

这是我的提交方法:

onSubmitUserDetails(value) {
    this.newUser = new User(this.userDetailsForm.value);
}

但是显然,使用嵌套密码formGroup时,this.newUser中没有我需要的密码:

  

{电子邮件:“ test @ test” matching_passwords:{密码:“ Test1”,   Confirm_password:“ Test1”}伪:“测试”条款:true}

我可以一一设置值,但是对于较大的表格可能会很长。有什么方便的方法可以将formGroup的值设置为一个类并使用嵌套密码formGroup解决问题?我们应该如何实现呢?

让我的User对象准确反映formGroups结构,然后在将对象发送到API时排除无用的字段(例如密码确认)是最好的解决方案吗?

如果我的User类中有一个嵌套对象(例如,说一本书集),又该如何转换嵌套的FormGroups以使其与类结构匹配呢?

1 个答案:

答案 0 :(得分:4)

您可以为此使用解构。将其视为表单的值:

{
  email: "test@test",
  matching_passwords: {
    password: "Test1",
    confirm_password: "Test1"
  },
  pseudo: "test",
  terms: true
}

您可以这样做:

onSubmitUserDetails(value) {
  const { email, pseudo } = value;
  const password = value.matching_passwords.password;
  const user = { pseudo, email, password }
  this.newUser = new User(user);
}

更新

还有其他方法可以使此工作正常进行。由于您的表单的密码部分不同(matching_passwords,并且我假设您不想将其发送到API进行保存,因此我只选择了相关字段。

  1. 如果您想直接利用表单中的数据,则必须以value与您的Class定义相匹配的方式设计表单。(最适合具有嵌套的对象)

  2. 您还可以使用扩展运算符(...)扩展表单值,然后将不相关的字段设置为null(最适合具有扁平结构的对象)

onSubmitUserDetails(value) {
  let user = {...value};
  user.password = value.matching_passwords.password;
  user.matching_passwords = null;
  user.terms = null;
  this.newUser = new User(user);
}