6

我正在尝试在 Angular 2 中实现模型驱动的表单。我的数据模型的结构如下:

archive (FormGroup)
    name (FormControl)
    description (FormControl)
    connection (FormGroup)
        url (FormControl)
        authentication (FormGroup)
            username (FormControl)
            password (FormControl)

在此数据模型中,顶级名称是必需的,但描述字段是可选的。我可以将所需的验证器应用于名称,并从描述中省略验证器。

对于连接,我希望它是可选的,但如果存在连接,则它的 URL 成为必需的。同样对于连接的身份验证模型:它是可选的,但如果存在,则需要用户名和密码。

我正在尝试了解如何设置验证器来执行这些规则。我尝试从连接表单组中省略任何验证器,但这似乎需要我建立连接。我已经看到在线教程解释了如何在嵌套表单组上实现自定义验证,但没有任何内容描述如何使整个嵌套表单组成为可选。

有没有一种直接的方法可以用 Angular 2 FormGroup 实现这个模型?

4

1 回答 1

2

我有类似的需求,这是一种解决方法:

this.form = new FormGroup({
    'name': new FormControl(null, Validators.required),
    'description': new FormControl(null),
    'connection': new FormGroup({
        'url': new FormControl(null),
        'authentification': new FormGroup({
            'username': new FormControl(null, Validators.minLength(5)),
            'password': new FormControl(null),
        }, this.authentificationValidator.bind(this)),
    }, this.connectionValidator.bind(this))
});

2个验证器功能:

authentificationValidator(g: FormGroup): any {
    const username = g.get('username').value;
    const password = g.get('password').value;

    if( (username && !password) || (!username && password) ) {
        return {
            authentification: true
        };
    }
}

connectionValidator(g: FormGroup): any {
    const url = g.get('url').value;

    const authentification = g.get('authentification');
    const username = authentification.get('username').value;
    const password = authentification.get('password').value;

    if( (username || password) && !url ) {
      return {
          connection: true
      };
    }
}

对于输出,如果您只填写名称,您仍然会有:

{
  "name": null,
  "description": null,
  "connection": {
    "url": null,
    "authentification": {
      "username": null,
      "password": null
    }
  }
}

所以你必须有条件地创建一个新对象才能拥有:

{
  "name": null,
  "description": null,
  "connection": null
}

检查这个 plunker 来试验这个解决方案

于 2017-07-07T07:44:03.060 回答