Как синхронизировать c мой шаблон и машинописный код в angular реактивных формах, имеющих группы форм? Не удается найти контрольную ошибку - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть простая форма регистрации, имеющая userName, email, password, confirmPassword, dateOFBirth и gender.

У меня есть custom validator для моего password и confirmPassword.

Я также связал элементы управления формы с моим шаблоном. Но что-то не так, я думаю, что это связано с form grouping. У меня есть две группы, одна для всей формы, а затем для полей password и confirmPassword.

sign-up.component.ts

export class SignUpComponent implements OnInit {
  genders = ["Male", "Female"];

  isLoading: Boolean = false;
  error: string = null;

  signUpForm: FormGroup;
  formGroup: FormGroup;
  password: AbstractControl;
  confirmPassword: AbstractControl;
  userName: AbstractControl;
  email: AbstractControl;
  dateOfBirth: AbstractControl;
  gender: AbstractControl;

  constructor(private authService: AuthService) {}

  ngOnInit() {
    this.userName = new FormControl(null, Validators.required);
    this.email = new FormControl(null, [Validators.required, Validators.email]);
    this.dateOfBirth = new FormControl(null, Validators.required);
    this.gender = new FormControl("male");
    this.password = new FormControl(null, [
      Validators.required,
      Validators.minLength(8),
    ]);
    this.confirmPassword = new FormControl(null, Validators.required);
    this.formGroup = new FormGroup(
      {
        password: this.password,
        confirmPassword: this.confirmPassword,
      },
      {
        validators: this.matchPassword,
      }
    );

    this.signUpForm = new FormGroup({ passwordGroup: this.formGroup });

    // this.signUpForm = new FormGroup({
    //   userName: new FormControl(null, Validators.required),
    //   email: new FormControl(null, [Validators.required, Validators.email]),
    //   passwordGroup: new FormGroup(
    //     {
    //       password: new FormControl(null, [
    //         Validators.required,
    //         Validators.minLength(8),
    //       ]),
    //       confirmPassword: new FormControl(null, Validators.required),
    //     }{
    //       validator: this.matchPassword
    //   }
    //   ),
    //   dateOfBirth: new FormControl(null, Validators.required),
    //   gender: new FormControl("Male"),
    // });
  }
  onSubmit() {
   ---some logic----
  }

  matchPassword = (group: FormGroup): { [s: string]: boolean } => {
    return group.value.password === group.value.confirmPassword
      ? null
      : { unmatched: true };
  };
}

Закомментировано часть в коде, для этого мне пришлось ссылаться на элементы управления формы в моем шаблоне таким образом - this.signUpForm.get('email') this.signUpForm.get('passwordGroup.password'). Этот подход сработал. Но в этом случае я не смог прикрепить пользовательский валидатор.

sign-up.component. html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-md-4 col-md-offset-4">
      <div class="alert alert-danger" *ngIf="error">
        <p>{{ error }}</p>
      </div>
      <div *ngIf="isLoading" style="text-align: center;">
        <app-loading-spinner></app-loading-spinner>
      </div>
      <div *ngIf="!isLoading">
        <h1 style="text-align: center;" class="text-primary">Sign Up</h1>
        <form [formGroup]="signUpForm" (ngSubmit)="onSubmit()">
          <div class="form-group">
            <label for="username">Name</label>
            <input
              type="text"
              id="username"
              class="form-control"
              formControlName="userName"
            />
          </div>
          <div class="form-group">
            <label for="email" mt-8>Email</label>
            <input
              type="text"
              id="email"
              class="form-control"
              formControlName="email"
            />
            <span *ngIf="email.valid && email.touched" class="help-block"
              >Please enter a valid email!</span
            >
          </div>
          <div class="form-group">
            <label for="dateOfBirth">Date Of Birth</label>
            <input
              type="date"
              id="dateOfBirth"
              class="form-control"
              formControlName="dateOfBirth"
            />
          </div>
          <div formGroupName="passwordGroup">
            <div class="form-group">
              <label for="password">Password</label>
              <input
                type="password"
                id="password"
                class="form-control"
                formControlName="password"
              />
              <span
                *ngIf="!password.valid && password.touched"
                class="help-block"
                >Password must of minimum 8 characters!</span
              >
            </div>
            <div class="form-group">
              <label for="password">Confirm Password</label>
              <input
                type="password"
                id="confirmPassword"
                class="form-control"
                formControlName="confirmPassword"
              />
              <span
                *ngIf="!confirmPassword.valid && confirmPassword.touched"
                class="help-block"
                >Please Confirm your password</span
              >
            </div>
            <div
              class="error"
              *ngIf="
                password.valid && confirmPassword.valid && formGroup.invalid
              "
            >
              Passwords don't match!
            </div>
          </div>

          <div>
            <label for="geder">Gender</label>
            <div class="radio" *ngFor="let gender of genders">
              <label>
                <input
                  type="radio"
                  [value]="gender"
                  formControlName="gender"
                />{{ gender }}<i class="fab fa-facebook-square"></i>
              </label>
            </div>
          </div>
          <button
            class="btn btn-primary btn-block"
            type="submit"
            [disabled]="!signUpForm.valid"
            style="cursor: pointer;"
          >
            Register
          </button>
        </form>
        <p style="text-align: center;">
          Already have an account?<a [routerLink]="['/login']">Log In</a>
        </p>
      </div>
    </div>
  </div>
</div>

Я считаю, что если я смогу сгруппировать форму правильно, она будет работать , Пожалуйста, помогите мне сделать это.

Вот ошибка -

core.js:4061 ERROR Error: Cannot find control with name: 'userName'
    at _throwError (forms.js:2540)
    at setUpControl (forms.js:2446)
    at FormGroupDirective.push../node_modules/@angular/forms/__ivy_ngcc__/fesm5/forms.js.FormGroupDirective.addControl (forms.js:5804)
    at FormControlName.push../node_modules/@angular/forms/__ivy_ngcc__/fesm5/forms.js.FormControlName._setUpControl (forms.js:6445)
    at FormControlName.push../node_modules/@angular/forms/__ivy_ngcc__/fesm5/forms.js.FormControlName.ngOnChanges (forms.js:6360)
    at FormControlName.wrapOnChangesHook_inPreviousChangesStorage (core.js:19422)
    at callHook (core.js:2919)

ERROR Error: Cannot find control with name: 'email'
    at _throwError (forms.js:2540)
    at setUpControl (forms.js:2446)
    at FormGroupDirective.push../node_modules/@angular/forms/__ivy_ngcc__/fesm5/forms.js.FormGroupDirective.addControl (forms.js:5804)

ERROR Error: Cannot find control with name: 'dateOfBirth'
    at _throwError (forms.js:2540)
    at setUpControl (forms.js:2446)
    at FormGroupDirective.push../node_modules/@angular/forms/__ivy_ngcc__/fesm5/forms.js.FormGroupDirective.addControl 

ERROR Error: Cannot find control with name: 'gender'
    at _throwError (forms.js:2540)
    at setUpControl (forms.js:2446)
    at FormGroupDirective.push../node_modules/@angular/forms/__ivy_ngcc__/fesm5/forms.js.FormGroupDirective.addControl (forms.js:5804)

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

Я вам посоветую импортный формбилдер. Разделите группы форм на две части, как показано ниже, и назовите каждую группу форм в шаблоне формы.

constructor(private fb:FormBuilder){
}
ngOnInit(){
signUpForm = this.fb.group({
   infoGroup: this.fb.group({
   userName: ['', [Validators.required, Validator.minLength(2)]],
    email: ['', [Validators.required, Validator.email]]
   }),   
    passwordGroup: this.fb.group({
      password: ['',[Validators.required]],
      confirmPassword: [''],
    }),
  });
}


<div class="container">
  <div class="row">
    <div class="col-xs-12 col-md-4 col-md-offset-4">
      <div class="alert alert-danger" *ngIf="error">
        <p>{{ error }}</p>
      </div>
      <div *ngIf="isLoading" style="text-align: center;">
        <app-loading-spinner></app-loading-spinner>
      </div>
      <div *ngIf="!isLoading">
        <h1 style="text-align: center;" class="text-primary">Sign Up</h1>
        <form [formGroup]="signUpForm" (ngSubmit)="onSubmit()">
        <div formGroupName="infoGroup">
        
            <div class="form-group">
            <label for="username">Name</label>
            <input
              type="text"
              id="username"
              class="form-control"
              formControlName="userName"
            />
          </div>
          <div class="form-group">
            <label for="email" mt-8>Email</label>
            <input
              type="text"
              id="email"
              class="form-control"
              formControlName="email"
            />
            <span *ngIf="email.valid && email.touched" class="help-block"
              >Please enter a valid email!</span
            >
          </div>
        
        </div>
      
          <div formGroupName="passwordGroup">
            <div class="form-group">
              <label for="password">Password</label>
              <input
                type="password"
                id="password"
                class="form-control"
                formControlName="password"
              />
              <span
                *ngIf="!password.valid && password.touched"
                class="help-block"
                >Password must of minimum 8 characters!</span
              >
            </div>
            <div class="form-group">
              <label for="password">Confirm Password</label>
              <input
                type="password"
                id="confirmPassword"
                class="form-control"
                formControlName="confirmPassword"
              />
              <span
                *ngIf="!confirmPassword.valid && confirmPassword.touched"
                class="help-block"
                >Please Confirm your password</span
              >
            </div>
            <div
              class="error"
              *ngIf="
                password.valid && confirmPassword.valid && formGroup.invalid
              "
            >
              Passwords don't match!
            </div>
          </div>

          <div>
            <label for="geder">Gender</label>
            <div class="radio" *ngFor="let gender of genders">
              <label>
                <input
                  type="radio"
                  [value]="gender"
                  formControlName="gender"
                />{{ gender }}<i class="fab fa-facebook-square"></i>
              </label>
            </div>
          </div>
          <button
            class="btn btn-primary btn-block"
            type="submit"
            [disabled]="!signUpForm.valid"
            style="cursor: pointer;"
          >
            Register
          </button>
        </form>
        <p style="text-align: center;">
          Already have an account?<a [routerLink]="['/login']">Log In</a>
        </p>
      </div>
    </div>
  </div>
</div>
0 голосов
/ 26 апреля 2020

Я смог решить это ... Я сделал это изменение, и оно сработало.

this.signUpForm = new FormGroup({
      userName: this.userName,
      email: this.email,
      dateOfBirth: this.dateOfBirth,
      gender: this.gender,
      passwordGroup: this.formGroup,
    });
...