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 { }
材料.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 { }
表单路由.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 { }
请帮忙
解决方案
您在这里有两个主要错误:
将组件导入模块。做不到,只能导入模块。可以声明和导出组件。这导致您看到的错误。
通过将 FormModule 导入 MaterialModule 来导入循环模块,反之亦然。做不到。进口只能是一个方向。这导致您看到的警告实际上是阻止您重新编译的错误。
还有一些小错误,比如你混淆了模块逻辑和双重导入模块
下面修复....
材料模块,让它做它应该做的,导入和导出材料模块,NOTHING ELSE,移除反应表单导入,移除对 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 { }
app 模块,不要尝试导入表单组件,只需导入模块即可。不要重新导入材料模块,您可以在材料模块中执行此操作:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
NoopAnimationsModule,
MaterialModule, // do you really NEED the material module here?
FormModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
推荐阅读
- php - DHL PHP Express(DHL 全球网络服务)
- java - 了解 Spring Security 中 permitAll() 和 anonymous() 的区别
- android - notifyDataSetChanged() 不适用于 recyclerview
- angular - 如何在打字稿中格式化日期?
- sql-server - SQL Server 2016 从标准版升级到开发者版
- java - SODA oracle 12,授予 SODA_APP
- mono - 如何从 Mono 的响应式订阅中调用私有方法并在 Spring 5 中返回特定类型?
- mysql - 在 AWS RDS 上托管的数据库上导入 SQL 脚本期间出现 MySql 错误“max_allowed_packet”字节
- go - 将字节数组传递给插件函数
- python-3.x - 如何让 Flask 应用程序与 gunicorn 一起运行