- Essential Angular
- Victor Savkin Jeff Cross
- 414字
- 2021-07-02 22:56:27
Bootstrap and entry components
The bootstrap property defines the components that are instantiated when a module is bootstrapped. First, Angular creates a component factory for each of the bootstrap components. And then, at runtime, it'll use the factories to instantiate the components.
To generate less code, and, as a result, to produce smaller bundles, Angular won't generate component factories for any components of TalksModule. The framework can see their usage statically, it can inline their instantiation, so no factories are required. This is true for any component used statically (or declaratively) in the template.
For instance, let's look at TalkCmp:
@Component({
selector: 'talk-cmp',
template: `
{{talk.title}} {{talk.speaker}}
{{talk.rating | formatRating}}
<watch-button [talk]="talk"></watch-button>
<rate-button [talk]="talk"></rate-button>
`
})
class TalkCmp {
@Input() talk: Talk;
@Output() rate: EventEmitter;
//...
}
Angular knows, at compile time, that TalkCmp uses WatchButtonCmp and RateButtonCmp, so it can instantiate them directly, without any indirection or extra abstractions.
Now let's look at a different component that uses the router:
@Component({
selector: 'router-cmp',
template: `
<router-outlet></router-outlet>
`
})
class RouterCmp {}
@NgModule({
declarations: [RouterCmp],
imports: [BrowserModule, RouterModule, TalksModule],
bootstrap: [RouterCmp],
providers: [
{provide: ROUTES, useValue: [
{ path: 'talks', component: TalksCmp },
{ path: 'settings', component: SettingsCmp }
]}
]
})
class RouterModule {}
Angular cannot statically figure out what components can be loaded into the outlet, and, as a result, cannot instantiate them directly. Here we need the extra abstraction, we need the component factories for both TalksCmp and SettingsCmp. We can tell Angular to generate those by listing them as entry components.
@NgModule({
declarations: [RouterCmp],
imports: [BrowserModule, RouterModule, TalksModule],
bootstrap: [RouterCmp],
entryComponents: [TalksCmp, SettingsCmp],
providers: [
{provide: ROUTES, useValue: [
{ path: 'talks', component: TalksCmp },
{ path: 'settings', component: SettingsCmp }
]}
]
})
class RouterModule {}
Even though we do not use TalksCmp or SettingsCmp in any template, the router configuration is still static. And it is cumbersome to declare every component used by the router in the entry components. Because this is so common, Angular supports a special provider token to automatically pre-populate entryComponents.
@NgModule({
declarations: [RouterCmp],
imports: [BrowserModule, RouterModule, TalksModule],
bootstrap: [RouterCmp],
providers: [
{provide: ROUTES, useValue: [
{ path: 'talks', component: TalksCmp },
{ path: 'settings', component: SettingsCmp }
]},
{provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, \
useExisting: ROUTES}
]
})
class RouterModule {}
And when using RouterModule.forRoot or RouterModule.forChild, the router module takes care of it.
@NgModule({
declarations: [RouterCmp],
imports: [BrowserModule, TalksModule, RouterModule.forRoot([
{ path: 'talks', components: TalksCmp },
{ path: 'settings', components: SettingsCmp }
])],
bootstrap: [RouterCmp]
})
class RouterModule {}
- WildFly:New Features
- CentOS 7 Server Deployment Cookbook
- ASP.NET Core Essentials
- Mastering Python Scripting for System Administrators
- Architecting the Industrial Internet
- 跟小海龜學(xué)Python
- Elasticsearch Server(Third Edition)
- C語言程序設(shè)計(jì)同步訓(xùn)練與上機(jī)指導(dǎo)(第三版)
- HTML5與CSS3基礎(chǔ)教程(第8版)
- C語言程序設(shè)計(jì)
- Machine Learning in Java
- 搞定J2EE:Struts+Spring+Hibernate整合詳解與典型案例
- Java圖像處理:基于OpenCV與JVM
- Instant Automapper
- Getting Started with Electronic Projects