Reputation: 606
I have just started learning Angular and working through some tutorials. My project is generated by Angular CLI. I have generated a new component called navbar on top of the component that was generated when I created the project and I was trying to see if navbar loads up on my index.html upon start up. My navbar shows up only when I have both app in the index.html file, for example:
<body>
<app-root></app-root>
<app-navbar></app-navbar>
</body>
If I remove app-root from index.html like so:
<body>
<app-navbar></app-navbar>
</body>
My navbar app is not showing it anymore. Is that something that has to do with the app-root component? Is it because it is a root component and it has to be included in index.html all the time?
Here is my code:
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-navbar></app-navbar>
</body>
</html>
app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './component1/app.component';
import { NavbarComponent } from './navbar/navbar.component';
@NgModule({
declarations: [
AppComponent,
NavbarComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [
AppComponent,
NavbarComponent
]
})
export class AppModule { }
navbar.component.ts:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent {
constructor() {}
// tslint:disable-next-line: use-lifecycle-interface
ngOnInit() {
}
}
Upvotes: 4
Views: 6734
Reputation: 699
Angular attempts to find app-root tag and throws error that you can see in console of browser something like this:
Error: The selector "app-root" did not match any elements at ha.selectRootElement (main-*.js)
So rendering crashes, and navbar not showing
To avoid this issue add ngDoBootstrap method with conditionals to root app module:
@NgModule({
declarations: [],
imports: [BrowserModule, AppRoutingModule],
providers: [],
bootstrap: []
})
export class AppModule
{
ngDoBootstrap(appRef: ApplicationRef)
{
if (document.getElementsByTagName('app-root').length > 0)
{
appRef.bootstrap(AppComponent, 'app-root')
}
if (document.getElementsByTagName('app-navbar').length > 0)
{
appRef.bootstrap(NavbarComponent, 'app-navbar')
}
}
}
Upvotes: 1
Reputation: 24424
you can add multiple component to bootstrap but they must be from the same module
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent, HelloComponent, NavbarComponent ],
bootstrap: [ AppComponent ,NavbarComponent ]
})
export class AppModule { }
index.html
<my-app>loading</my-app>
<app-navbar>loading</app-navbar>
the angular app bootstrap from a single module like appmodule here
main.ts
platformBrowserDynamic().bootstrapModule(AppModule).then(ref => {
// Ensure Angular destroys itself on hot reloads.
if (window['ngRef']) {
window['ngRef'].destroy();
}
window['ngRef'] = ref;
// Otherwise, log the boot error
}).catch(err => console.error(err));
Upvotes: 1
Reputation: 2987
You must place the component selector inside app.component.html:
<app-navbar></app-navbar>
The <app-root>
tag is where the bootstraped component be displayed ( which is the AppComponent
by default). And usually you do not need more than 1 bootstraped component, so remove NavbarComponent
from bootstrap in AppModule.
In a higher lever view, you can consider your app as a tree of components which it's root is the AppComponent, so the child of AppComponent must be place inside app.component.html, and the child of NavBarComponent for example must be place inside navbar.component.html
.
Upvotes: 1