NullInjectorError: Нет поставщика для FormGroup! " - PullRequest
0 голосов
/ 06 ноября 2019

Я разрабатываю угловое приложение. Я реализовал компонент Dialog, целью которого является создание всплывающей модели, которая будет отображать форму для регистрации. Компонент выглядит следующим образом:

import { Component, OnInit, Inject } from '@angular/core';
import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import {MAT_RADIO_DEFAULT_OPTIONS } from '@angular/material';

@Component({
  selector: 'app-user-dialog',
  templateUrl: './user-dialog.component.html',
  styleUrls: ['./user-dialog.component.scss'],
  providers: [
    {provide: MAT_RADIO_DEFAULT_OPTIONS, useValue: { color: 'accent' }},
    { provide: MatDialogRef, useValue: {} }
    // ,{ provide: MAT_DIALOG_DATA, useValue: [] }
  ]
})
export class UserDialogComponent implements OnInit {


  public form: FormGroup;

  private validateAreEqual(fieldControl: FormControl) {
    return fieldControl.value === this.form.get('password').value ? null : {
        NotEqual: true
    };
  }

  constructor(
    private dialogRef: MatDialogRef<UserDialogComponent>,
    @Inject(MAT_DIALOG_DATA) data) {
     }

  ngOnInit() {
    this.form = new FormGroup({
      gender: new FormControl('', Validators.required),
      lastName: new FormControl('', Validators.required),
      firstName: new FormControl('', Validators.required),
      email: new FormControl('', Validators.compose([Validators.email, Validators.required])),
      password: new FormControl('', Validators.compose([Validators.required, Validators.pattern('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&].{8,}')])),
      // tslint:disable-next-line: max-line-length
      confirmPassword: new FormControl('', Validators.compose([Validators.required, Validators.pattern('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&].{8,}'), this.validateAreEqual.bind(this)]))
    });
  }

  save() {
    this.dialogRef.close(this.form.value);
  }

  close() {
    this.dialogRef.close();
  }

}

Шаблон - это форма, в которой я определяю группу FormGroup. Вот код

<h2 mat-dialog-title>S'enregistrer</h2>

<mat-dialog-content [formGroup]="form">
    <mat-form-field>
        <mat-radio-group name="gender"  required formControlName="gender">
            <mat-radio-button labelPosition="after" value="F">Mme</mat-radio-button>
            <mat-radio-group labelPosition="after" value="M">Mr</mat-radio-group>
        </mat-radio-group>
        <mat-error *ngIf="form.get('gender').hasError('required')">Le sexe homme ou femme est obligatoire.</mat-error>

        <mat-label>Nom</mat-label>
        <input matInput required type="text" placeholder="Nom" formControlName="lastName">
        <mat-error *ngIf="form.get('lastName').hasError('required')">Le nom est obligatoire.</mat-error>

        <mat-label>Prénom</mat-label>
        <input matInput required type="text" placeholder="Prénom" formControlName="firstName">
        <mat-error *ngIf="form.get('firstName').hasError('required')">Le prénom est obligatoire.</mat-error>

        <mat-label>E-mail</mat-label>
        <input matInput required type="email" placeholder="E-mail" formControlName="email">
        <mat-error *ngIf="form.get('email').hasError('required')">L'email est obligatoire.</mat-error>
        <mat-error *ngIf="form.get('email').hasError('email')">L'email n'est pas valide.</mat-error>

        <mat-label>Mot de passe</mat-label>
        <input matInput required type="password" placeholder="Mot de passe" formControlName="password">
        <mat-error *ngIf="form.get('password').hasError('required')">Le mot de passe est obligatoire.</mat-error>
        <mat-error *ngIf="form.get('password').hasError('pattern')">Le mot de passe n'est pas valide : il doit contenir au moins 8 caractères, un caractère minuscule, un caractère majuscule, un chiffre et un caractère spécial.</mat-error>

        <mat-label>Confirmation du mot de passe</mat-label>
        <input matInput required type="password" placeholder="Confirmation du mot de passe" formControlName="confirmPassword">
        <mat-error *ngIf="form.get('confirmPassword').hasError('required')">La confirmation du mot de passe est obligatoire.</mat-error>
        <mat-error *ngIf="form.get('confirmPassword').hasError('pattern')">La confirmation du mot de passe n'est pas valide : elle doit contenir au moins 8 caractères, un caractère minuscule, un caractère majuscule, un chiffre et un caractère spécial.</mat-error>     
        <mat-error *ngIf="form.get('confirmPassword').hasError('NotEqual')">Le mot de passe et la confirmation du mot de passe doivent être les mêmes.</mat-error>

    </mat-form-field>
</mat-dialog-content>
<mat-dialog-actions>
    <button class="mat-raised-button"(click)="close()">Close</button>
    <button class="mat-raised-button mat-primary"(click)="save()">Save</button>
</mat-dialog-actions>

Я вызываю его из другого компонента с помощью метода:

openDialog() {
  console.log('ca passe');
  const dialogConfig = new MatDialogConfig();
  dialogConfig.disableClose = true;
  dialogConfig.autoFocus = true;
  dialogConfig.position = {
    top:  '0',
    right: '0'
  };
  dialogConfig.width = '50%' ;
  dialogConfig.height = '350px' ;
  console.log(dialogConfig);
  this.dialog.open(UserDialogComponent, dialogConfig);
}

Но я получаю ошибку:

ERROR NullInjectorError: "StaticInjectorError(AppModule)[UserDialogComponent -> FormGroup]: 
  StaticInjectorError(Platform: core)[UserDialogComponent -> FormGroup]: 
    NullInjectorError: No provider for FormGroup!"

Не знаюне вижу, где проблема. Не могли бы вы помочь мне?

Ответы [ 2 ]

1 голос
/ 06 ноября 2019

Убедитесь, что вы импортируете FormsModule, ReactiveFormsModule в свой sharedModule.ts, если вы используете это или app.module.ts. Если вы импортируете в ShareModule.ts, убедитесь, что вы реэкспорт их. пример: // общий модуль

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [FormsModule, ReactiveFormsModule],
  declarations: [
    ...
  ],
  exports: [
    FormsModule, ReactiveFormsModule,
  ],
  providers: [],
})
export class SharedModule {}

или если только app.module.ts

import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { SharedModule } from 'src/app/shared/sharedModule';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule, <!----- if you use sharedModule remove
    ReactiveFormsModule <!----- if you use sharedModule remove
    SharedModule, 
    AppRoutingModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}
0 голосов
/ 06 ноября 2019

наконец, я нашел способ создания FormGroup. Вот решение

export class UserDialogComponent implements OnInit {


  public dialogFormGroup: FormGroup;



  constructor(
    private formBuilder: FormBuilder,
    private dialogRef: MatDialogRef<UserDialogComponent>,
    @Inject(MAT_DIALOG_DATA) data) {
     }

  ngOnInit() {
    this.dialogFormGroup = this.formBuilder.group({
      gender: ['', Validators.required],
      lastName: ['', Validators.required],
      firstName: new FormControl('', Validators.required),
      email: ['', Validators.compose([Validators.email, Validators.required])],
      password: ['', Validators.compose([Validators.required, Validators.pattern('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&].{8,}')])],
      // tslint:disable-next-line: max-line-length
      confirmPassword: ['', Validators.compose([Validators.required, Validators.pattern('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&].{8,}'), this.validateAreEqual.bind(this)])]
    });
  }

Не могли бы вы объяснить, почему мне нужен FormBuilder и я не могу напрямую создать FormGroup (новая FormGroup ({...

...