Я создаю свое собственное веб-приложение, используя Angular 6, Angular Material и Angular CLI.Изначально у него был только один модуль, и в процессе разработки я решил провести рефакторинг: добавить функциональные модули и поместить мои существующие функциональные компоненты в различные функциональные модули, чтобы справиться с растущей сложностью.И вот что я сделал:
- добавление модуля с помощью угловой команды CLI:
ng g m ai --module app --routing
- помещение объявления компонента в
ai.module.ts
и удаление исходного объявления в app.module.ts - положить путь маршрутизации в
ai-routing.module.ts
и удалить исходный путь маршрутизации в app.module.ts - импортировать все необходимые общие службы, каналы и т. Д. В модуль
Проблема в том, что я даже не могу заставить этот самый первый новый функциональный модуль работать должным образом.В консоли браузера есть ошибка: ERROR TypeError: Cannot read property 'description' of undefined
, где 'description' - это свойство Observable, и я интерполирую его в шаблон с асинхронным каналом.И только некоторые части моего приложения (панель навигации и нижний колонтитул) отображаются.
Структура проекта
Мое приложение в браузере после добавления нового модуля ngModule, тамэто сообщения об ошибках в консоли
Подробные сообщения об ошибках, они повторяются
Так кто-нибудь может научить меня, как правильно реорганизовать мой проект?Вот соответствующий код, спасибо заранее!
aiservice.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { map, tap } from 'rxjs/operators';
import { AimodelService } from '../../shared/services/aimodel.service';
import { ModelCategory, modelcategories } from
'../../shared/models/categoryAndReceipt.model';
import { Observable } from 'rxjs';
@Component({
selector: 'app-aiservice',
templateUrl: './aiservice.component.html',
styleUrls: ['./aiservice.component.scss']
})
export class AiServiceComponent implements OnInit {
modelCategories: ModelCategory[];
modelList: Object[];
displayModelList$: Observable<Object[]> = new Observable();
selectedCategory$: Observable<ModelCategory>;
constructor(
private aimodelservice: AimodelService,
private route: ActivatedRoute
) {}
public ngOnInit() {
console.log('init');
this.selectedCategory$ = this.route.paramMap.pipe(
map((params: ParamMap) => {
return modelcategories.find(
category => category.abbr === params.get('abbr')
);
}),
tap(category => {
this.displayModelList$ = this.aimodelservice.getModel().pipe(
map(models =>
models.filter(model => {
return model['category'] === category.categoryId;
}).reverse()
)
);
})
);
}
}
aiservice.component.html:
<div fxLayout="column" fxLayoutAlign="space-between">
<div fxFlex>
<h1>{{(selectedCategory$ | async).title}}
<mat-icon matTooltipClass="appTooltip" matTooltipShowDelay=500 [matTooltip]='(selectedCategory$ | async).description'
matTooltipPosition='after' color="primary">
contact_support
</mat-icon>
</h1>
</div>
<div id="services" fxLayout="column">
<mat-accordion fxFlex *ngFor="let model of displayModelList$ | async;let i=index">
<mat-expansion-panel #i (mouseenter)="i.open()" (mouseleave)="i.close()" (opened)="panelOpenState = true"
(closed)="panelOpenState = false">
<mat-expansion-panel-header class="panelheader" fxLayout="row" fxLayoutAlign="start">
<mat-panel-title fxFlex="35vw">
<h4>
<mat-icon color="primary">offline_bolt</mat-icon> {{model.title}}
</h4>
</mat-panel-title>
<mat-panel-description fxFlex="35vw" fxLayout="row" fxLayoutAlign="start">
<span fxFlex="70%"></span>
<mat-icon fxFlexAlign="center" color="primary">account_balance_wallet</mat-icon>
<span fxFlexAlign="center">COST:{{model.price}} FRS</span>
</mat-panel-description>
</mat-expansion-panel-header>
<div fxLayout="column">
<p fxFlex>{{model.description}}</p>
<div fxLayout="row">
<button mat-raised-button [routerLink]="[model.id]" fxFlex="8rem" fxFlexOffset="83%" mat-button>
<mat-icon color="primary">attach_money</mat-icon>Purchase
</button>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
ai-routing.module.ts:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AiServiceComponent } from './aiservice/aiservice.component';
const routes: Routes = [
{
path: ':abbr',
component: AiServiceComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AiRoutingModule {}
ai.module.ts:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AiRoutingModule } from './ai-routing.module';
import { AiServiceComponent } from './aiservice/aiservice.component';
import { SharedModule } from '../shared/shared.module';
@NgModule({
imports: [
CommonModule,
AiRoutingModule,
SharedModule
],
declarations: [
AiServiceComponent
]
})
export class AiModule { }
app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule, Routes } from '@angular/router';
import { OverlayContainer } from '@angular/cdk/overlay';
// project components import
import { AppComponent } from './app.component';
import { UseraccountComponent } from './useraccount/useraccount.component';
import { EDIComponent } from './edi/edi.component';
import { EdiIntroComponent } from './edi-intro/edi-intro.component';
import { Edi2Component } from './edi2/edi2.component';
import { AddModelComponent } from './forms/add-model/add-model.component';
import { PurchaseModelComponent } from './forms/purchase-model/purchase- model.component';
import { TopnavbarComponent } from './topnavbar/topnavbar.component';
import { FooterComponent } from './footer/footer.component';
import { FrsConvertPipe } from './useraccount/frs-convert.pipe';
import { MaterialDesignFrameworkModule } from 'angular6-json-schema-form';
import { AiformModelComponent } from './forms/aiform-model/aiform- model.component';
import { SharedModule } from './shared/shared.module';
import { AiModule } from './ai/ai.module';
const appRoutes: Routes = [
{
path: '',
redirectTo: '/account',
pathMatch: 'full'
},
{
path: 'account',
component: UseraccountComponent
},
{
path: 'add-model',
component: AddModelComponent,
},
{
path: ':abbr/:modelId',
component: PurchaseModelComponent
},
{
path: ':abbr/:modelId/form',
component: AiformModelComponent
}
];
@NgModule({
declarations: [
AppComponent,
UseraccountComponent,
EDIComponent,
EdiIntroComponent,
Edi2Component,
AddModelComponent,
PurchaseModelComponent,
TopnavbarComponent,
FooterComponent,
FrsConvertPipe,
AiformModelComponent,
],
imports: [
RouterModule.forRoot(
appRoutes,
{ enableTracing: false, onSameUrlNavigation : 'reload' } // <--debugging purposes only
),
BrowserModule,
BrowserAnimationsModule,
MaterialDesignFrameworkModule,
SharedModule,
AiModule
],
schemas: [ NO_ERRORS_SCHEMA ],
providers: [],
bootstrap: [AppComponent],
entryComponents: []
})
export class AppModule {
constructor(overlayContainer: OverlayContainer) {
overlayContainer.getContainerElement().classList.add('menu-theme');
}
}