Forms 重复使用单独的5个反应式表单元素

Forms 重复使用单独的5个反应式表单元素,forms,angular5,reactive,Forms,Angular5,Reactive,我仍在学习Angular 5,并已开始使用“反应式”表单模型。然而,我能找到的几乎每个示例和教程都让您在一个模板中创建整个表单。通常在AngularJS 1.x中,我们会将每个字段存储在它自己的指令中,然后将它们连接在一起以创建一个表单来减少重复 有没有一种方法可以让Angular 5反应式表单只使用一个文件并包含模板和所有验证?我可以分为两部分来了解如何实现这一点,其中我将有一个包含表单元素HTML、验证消息等的组件。但是,您还需要在完整表单的组件中创建FormControl,并为其提供默认值

我仍在学习Angular 5,并已开始使用“反应式”表单模型。然而,我能找到的几乎每个示例和教程都让您在一个模板中创建整个表单。通常在AngularJS 1.x中,我们会将每个字段存储在它自己的指令中,然后将它们连接在一起以创建一个表单来减少重复

有没有一种方法可以让Angular 5反应式表单只使用一个文件并包含模板和所有验证?我可以分为两部分来了解如何实现这一点,其中我将有一个包含表单元素HTML、验证消息等的组件。但是,您还需要在完整表单的组件中创建FormControl,并为其提供默认值和验证


也许这是非常常见的,我只是没有正确地搜索它,但如果有人能向我指出任何模式、教程或帮助,我将非常感谢,因为我觉得这是我的表单缺少的最后一块。谢谢大家!

如果其他人遇到这种情况,我能找到的最佳答案(至少有许多其他开发人员使用过,即使不是最佳实践)是在父“主表单”组件中创建一个FormGroup,然后创建一个新FormControl并将其附加到该FormGroup。例如,以下是可重用表单控件的组件:

import {Component, OnInit, Input} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';

@Component({
  selector: 'app-project-length',
  templateUrl: './project-length.component.html',
  styleUrls: ['./project-length.component.css']
})
export class ProjectLengthComponent implements OnInit {

 @Input() isFormSubmitted: boolean;
 @Input() projectForm: FormGroup;

 constructor() {
 }

 ngOnInit() {
 this.projectForm.addControl('projectLength', new FormControl(0, [Validators.required, this.hasCorrectLength]));
 }

 hasCorrectLength(control: FormControl): {[s: string]: boolean} {
   const length: number = control.value;
  if (length < 2 || length > 10) {
    return { 'incorrectLength' : true };
  }
  return null;
}

}
从'@angular/core'导入{Component,OnInit,Input};
从'@angular/forms'导入{FormControl,FormGroup,Validators};
@组成部分({
选择器:“应用程序项目长度”,
templateUrl:'./project length.component.html',
样式URL:['./项目长度.component.css']
})
导出类ProjectLength组件实现OnInit{
@Input()isFormSubmitted:boolean;
@Input()项目表单:FormGroup;
构造函数(){
}
恩戈尼尼特(){
this.projectForm.addControl('projectLength',新FormControl(0,[Validators.required,this.hasCorrectLength]);
}
hasCorrectLength(控件:FormControl):{[s:string]:布尔值}{
常量长度:number=control.value;
如果(长度<2 | |长度>10){
返回{'incorrectLength':true};
}
返回null;
}
}
以下是该表单元素组件的模板:

<div class="form-group" [formGroup]="projectForm">
<label for="project-length">project length</label>
<input
  class="form-control"
  type="number"
  id="project-length"
  placeholder="Enter project length"
  formControlName="projectLength"
/>
<span class="help-block" 
  *ngIf="!projectForm.controls['projectLength'].valid && (projectForm.controls['projectLength'].touched || isFormSubmitted)">
    please enter a project length between 2 and 9
</span>
import { Component, OnInit } from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import { Status} from '../shared/Status';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
  projectForm: FormGroup;
  statuses: Array<Status> = [
    {id: 1, name: 'Critical'},
    {id: 2, name: 'Stable'},
    {id: 3, name: 'Finished'}
  ];
  formSubmitted: boolean = false;

  ngOnInit() {
    this.projectForm = new FormGroup({
      namey: new FormControl(null, [Validators.required, this.cannotBeTest1]),
      email: new FormControl(null, [Validators.required, Validators.email]),
      status: new FormControl('1')
    });
  }

  onSubmit() {
    console.log(this.projectForm);

    this.formSubmitted = true;
    if (this.projectForm.valid) {
    console.log('Form data:');
    console.log(this.projectForm);
  }
}
cannotBeTest1(control: FormControl): {[s: string]: boolean} {
  ...
}
}
<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form class="ui form-vertical" [formGroup]="projectForm" (ngSubmit)="onSubmit()">
        ...
        <app-project-length [projectForm]="projectForm" [isFormSubmitted]="formSubmitted"></app-project-length>
        ...

项目长度
请输入介于2和9之间的项目长度

下面是父表单的组件(它已经有一些我正在编写的教程中的内置表单元素,并且只有一个可重用的表单元素组件):

从'@angular/core'导入{Component,OnInit};
从'@angular/forms'导入{FormControl,FormGroup,Validators};
从“../shared/Status”导入{Status};
@组成部分({
选择器:'应用程序根',
templateUrl:“./app.component.html”,
样式URL:['./app.component.css']
})
导出类AppComponent实现OnInit{
项目形式:FormGroup;
状态:数组=[
{id:1,名称:'Critical'},
{id:2,名称:'Stable'},
{id:3,名称:'Finished'}
];
formSubmitted:boolean=false;
恩戈尼尼特(){
this.projectForm=新表单组({
namey:newformcontrol(null,[Validators.required,this.cannotBeTest1]),
电子邮件:新FormControl(空,[Validators.required,Validators.email]),
状态:新FormControl('1')
});
}
onSubmit(){
console.log(this.projectForm);
this.formSubmitted=true;
if(this.projectForm.valid){
log('formdata:');
console.log(this.projectForm);
}
}
cannotBeTest1(控件:FormControl):{[s:string]:boolean}{
...
}
}
以下是主要表单组件模板的重要部分:

<div class="form-group" [formGroup]="projectForm">
<label for="project-length">project length</label>
<input
  class="form-control"
  type="number"
  id="project-length"
  placeholder="Enter project length"
  formControlName="projectLength"
/>
<span class="help-block" 
  *ngIf="!projectForm.controls['projectLength'].valid && (projectForm.controls['projectLength'].touched || isFormSubmitted)">
    please enter a project length between 2 and 9
</span>
import { Component, OnInit } from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import { Status} from '../shared/Status';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
  projectForm: FormGroup;
  statuses: Array<Status> = [
    {id: 1, name: 'Critical'},
    {id: 2, name: 'Stable'},
    {id: 3, name: 'Finished'}
  ];
  formSubmitted: boolean = false;

  ngOnInit() {
    this.projectForm = new FormGroup({
      namey: new FormControl(null, [Validators.required, this.cannotBeTest1]),
      email: new FormControl(null, [Validators.required, Validators.email]),
      status: new FormControl('1')
    });
  }

  onSubmit() {
    console.log(this.projectForm);

    this.formSubmitted = true;
    if (this.projectForm.valid) {
    console.log('Form data:');
    console.log(this.projectForm);
  }
}
cannotBeTest1(control: FormControl): {[s: string]: boolean} {
  ...
}
}
<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form class="ui form-vertical" [formGroup]="projectForm" (ngSubmit)="onSubmit()">
        ...
        <app-project-length [projectForm]="projectForm" [isFormSubmitted]="formSubmitted"></app-project-length>
        ...

...
...