I'm learning Angular and trying to understand how RouterModule
works with other modules. Say I have a simple AppModule
as follows.
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { AppComponent } from "./app.component";
import { RouterModule, Routes } from "@angular/router";
import { MainComponent } from "./main/main.component";
import { FeatureComponent } from "./feature/feature.component";
const routes: Routes = [
{
path: "",
component: MainComponent,
},
{
path: "feature",
component: FeatureComponent,
},
];
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, RouterModule.forRoot(routes)],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
Neither MainComponent
or FeatureComponent
are declared in the declarations property of any AppModule but this code still works. What's going on here?
I'm reading this article about template contexts in Angular. So in this case am I correct in understanding that these components don't have a template context since they are not declared in any module and thus will only be able to support standard HTML/CSS/JS and not the typical features you would get in an Angular component?
Now say I want to create a WidgetComponent
that in used in both MainComponent
and FeatureComponent
. If I just add WidgetComponent
to the declarations of AppModule
I get an error in the other components saying "app-widget is not a known element".
@NgModule({
declarations: [AppComponent, WidgetComponent],
imports: [BrowserModule, RouterModule.forRoot(routes)],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
'app-widget' is not a known element:
- If 'app-widget' is an Angular component, then verify that it is part of this module.
- If 'app-widget' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
This makes sense as neither MainComponent
or FeatureComponent
are declared in AppModule
where WidgetComponent
is declared so again they are not in the same template context. Is my understanding of this correct?
To fix this I can declare all three components in AppModule
.
@NgModule({
declarations: [
AppComponent,
WidgetComponent,
MainComponent,
FeatureComponent,
],
imports: [BrowserModule, RouterModule.forRoot(routes)],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
...or create a separate modules for the components and import them into one another.
@NgModule({
declarations: [WidgetComponent],
imports: [CommonModule],
exports: [WidgetComponent],
})
export class WidgetModule {}
@NgModule({
declarations: [MainComponent],
imports: [CommonModule, WidgetModule],
})
export class MainModule {}
@NgModule({
declarations: [FeatureComponent],
imports: [CommonModule, WidgetModule],
})
export class FeatureModule{}
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, RouterModule.forRoot(routes)],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
But in this 2nd solution I don't need to import any of the other modules into AppModule
I can simply pass the component classes directly to the RouterModule
. So what I understand from this is the template context of a component is defined simply by the module where it is declared. Is that right?