html - خطای ReferenceError: نمیتوان به 'MaterialModule' قبل از مقداردهی اولیه دسترسی پیدا کرد


من در حال کار روی یک فرم ساده برای یک پروژه شخصی هستم و سعی میکنم یک فرم تلفن ایجاد کنم و از این مثال استفاده کنم: https://material.angular,.io/components/form-field/examples و بعد از اینکه همه چیز را تنظیم میکنم این خطا را دریافت میکنم و با اینکه همه چیز مرتبط با فرم تلفن را حذف میکنم، همچنان همان مشکل باقی میماند.

form.component.ts

import { Component, OnInit } from '@angular/core';
import { Builder } from 'protractor';
import {FocusMonitor} from '@angular/cdk/a11y';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {ElementRef, Input, OnDestroy, Optional, Self} from '@angular/core';
import {FormBuilder, FormGroup, ControlValueAccessor, NgControl} from '@angular/forms';
import {MatFormFieldControl} from '@angular/material';
import {Subject} from 'rxjs';

@Component({
  selector: 'app-form',
  templateUrl: './form.component.html',
  styleUrls: ['./form.component.scss'],
  providers: [{provide: MatFormFieldControl, useExisting: MyTelInput}],
  host: {
    '[class.example-floating]': 'shouldLabelFloat',
    '[id]': 'id',
    '[attr.aria-describedby]': 'describedBy',
  }
})

export class MyTelInput implements ControlValueAccessor, MatFormFieldControl<MyTel>, OnDestroy {
  static nextId = 0;

  parts: FormGroup;
  stateChanges = new Subject<void>();
  focused = false;
  errorState = false;
  controlType = 'example-tel-input';
  id = `example-tel-input-${MyTelInput.nextId++}`;
  describedBy = '';
  onChange = (_: any) => {};
  onTouched = () => {};

  get empty() {
    const {value: {area, exchange, subscriber}} = this.parts;

    return !area && !exchange && !subscriber;
  }

  get shouldLabelFloat() { return this.focused || !this.empty; }

  @Input()
  get placeholder(): string { return this._placeholder; }
  set placeholder(value: string) {
    this._placeholder = value;
    this.stateChanges.next();
  }
  private _placeholder: string;

  @Input()
  get required(): boolean { return this._required; }
  set required(value: boolean) {
    this._required = coerceBooleanProperty(value);
    this.stateChanges.next();
  }
  private _required = false;

  @Input()
  get disabled(): boolean { return this._disabled; }
  set disabled(value: boolean) {
    this._disabled = coerceBooleanProperty(value);
    this._disabled ? this.parts.disable() : this.parts.enable();
    this.stateChanges.next();
  }
  private _disabled = false;

  @Input()
  get value(): MyTel | null {
    const {value: {area, exchange, subscriber}} = this.parts;
    if (area.length === 3 && exchange.length === 3 && subscriber.length === 4) {
      return new MyTel(area, exchange, subscriber);
    }
    return null;
  }
  set value(tel: MyTel | null) {
    const {area, exchange, subscriber} = tel || new MyTel('', '', '');
    this.parts.setValue({area, exchange, subscriber});
    this.stateChanges.next();
  }

  constructor(
    formBuilder: FormBuilder,
    private _focusMonitor: FocusMonitor,
    private _elementRef: ElementRef<HTMLElement>,
    @Optional() @Self() public ngControl: NgControl) {

    this.parts = formBuilder.group({
      area: '',
      exchange: '',
      subscriber: '',
    });

    _focusMonitor.monitor(_elementRef, true).subscribe(origin => {
      if (this.focused && !origin) {
        this.onTouched();
      }
      this.focused = !!origin;
      this.stateChanges.next();
    });

    if (this.ngControl != null) {
      this.ngControl.valueAccessor = this;
    }
  }

  ngOnDestroy() {
    this.stateChanges.complete();
    this._focusMonitor.stopMonitoring(this._elementRef);
  }

  setDescribedByIds(ids: string[]) {
    this.describedBy = ids.join(' ');
  }

  onContainerClick(event: MouseEvent) {
    if ((event.target as Element).tagName.toLowerCase() != 'input') {
      this._elementRef.nativeElement.querySelector('input')!.focus();
    }
  }

  writeValue(tel: MyTel | null): void {
    this.value = tel;
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }

  _handleInput(): void {
    this.onChange(this.parts.value);
  }
}
export class MyTel {
  constructor(public area: string, public exchange: string, public subscriber: string) {}
}

export class FormComponent implements OnInit {

  public formGroup: FormGroup;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      name: '',
      lastname: '',
      option: '',
      checkbox: '',
      masculino: '',
      femenino: '',
      email:'',
    });
  }

}

form.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { FormRoutingModule } from './form-routing.module';
import { FormComponent } from './form/form.component';
import { MaterialModule } from '../material/material.module';
import { FormBuilder } from '@angular/forms';



@NgModule({
  declarations: [FormComponent],
  imports: [
    CommonModule,
    FormRoutingModule, 
    MaterialModule
  ],
  providers: [
    FormBuilder
  ]
})
export class FormModule { }

material.module.ts

import { NgModule } from '@angular/core';
import { 
  MatTableModule, 
  MatPaginatorModule, 
  MatFormFieldModule, 
  MatSelectModule, 
  MatInputModule, 
  MatCheckboxModule, 
  MatRadioModule} from '@angular/material';
import { ReactiveFormsModule } from '@angular/forms';
import { FormModule } from '../form/form.module';
import { FormComponent } from '../form/form/form.component';

const materialModules = [
  MatTableModule,
  MatPaginatorModule,
  MatFormFieldModule,
  ReactiveFormsModule,
  MatSelectModule,
  MatInputModule,
  MatRadioModule,
  FormModule, 
  FormComponent,
  MatCheckboxModule,
];

@NgModule({
  exports: materialModules,
  imports: materialModules
})
export class MaterialModule { }

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { MaterialModule } from './modules/material/material.module';
import { MatSelectModule, MatInputModule, MatCheckbox, MatRadioModule } from '@angular/material';
import { MatFormFieldModule } from '@angular/material/form-field';
import { FormModule } from './modules/form/form.module';
import { FormComponent } from './modules/form/form/form.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    NoopAnimationsModule,
    MaterialModule,
    MatSelectModule,
    MatInputModule,
    MatFormFieldModule,
    MatRadioModule,
    FormModule,
    FormComponent
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

form-routing.component.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { FormComponent } from './form/form.component';


const routes: Routes = [{path: '', component: FormComponent}];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class FormRoutingModule { }

لطفاً کمک کنید

پاسخ شماره ۱

شما در اینجا ۲ اشتباه عمده دارید:

  1. وارد کردن یک کامپوننت به یک ماژول. این امکانپذیر نیست، فقط ماژولها قابل وارد کردن هستند. کامپوننتها میتوانند اعلام و صادر شوند. این باعث خطایی است که شما مشاهده میکنید.

  2. وارد کردن چرخهای ماژولها با وارد کردن FormModule به MaterialModule و بالعکس. نمیتوان آن را انجام داد. واردات تنها میتوانند در یک جهت باشند. این باعث هشداری که میبینید میشود که در واقع یک خطا است و از بازکامپایل جلوگیری میکند.

و بعضی خطاهای جزئی، مثل اینکه دارید منطق ماژول را با دوباره وارد کردن ماژولها قاطی میکنید

اصلاحات زیر....

ماژول مواد، بگذارید آن کاری را که قرار است انجام دهد انجام دهد، ماژولهای مواد را وارد و صادر کنید، هیچ چیز دیگری، واردات فرمهای واکنشی را حذف کنید، ارجاع چرخهای به FormsModule را حذف کنید، واردات کامپوننت فرم را حذف کنید:

import { NgModule } from '@angular/core';
import { 
  MatTableModule, 
  MatPaginatorModule, 
  MatFormFieldModule, 
  MatSelectModule, 
  MatInputModule, 
  MatCheckboxModule, 
  MatRadioModule} from '@angular/material';

const materialModules = [
  MatTableModule,
  MatPaginatorModule,
  MatFormFieldModule,
  MatSelectModule,
  MatInputModule,
  MatRadioModule,
  MatCheckboxModule,
];

@NgModule({
  exports: materialModules,
  imports: materialModules
})
export class MaterialModule { }

ماژول فرم، ماژول فرمهای واکنشی را اینجا وارد کنید (فرم بیلدر را ارائه ندهید)، کامپوننت فرم خود را صادر کنید تا بتوانید از آن در ماژولهای دیگر استفاده کنید:

@NgModule({
  declarations: [FormComponent],
  imports: [
    CommonModule, // if you have a common module, you could import / export the reactive forms module there if it's more appropriate and then you don't need to import it again here.
    FormRoutingModule, 
    MaterialModule,
    ReactiveFormsModule // do this here, don't provide the form builder
  ],
  exports: [
    FormComponent // if you want to use this component in other modules, export here and import the MODULE
  ]
})
export class FormModule { }

ماژول اپ، سعی نکن کامپوننت فرم را وارد کنی، فقط ماژول را وارد کن. ماژولهای متریال را دوباره وارد نکن، این کار را در ماژول متریال انجام بده:

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    NoopAnimationsModule,
    MaterialModule, // do you really NEED the material module here?
    FormModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }