- 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 {}
- ASP.NET Web API:Build RESTful web applications and services on the .NET framework
- FuelPHP Application Development Blueprints
- MySQL數(shù)據(jù)庫應用與管理 第2版
- HTML5+CSS3網(wǎng)站設計教程
- 單片機應用技術
- TypeScript實戰(zhàn)指南
- INSTANT Passbook App Development for iOS How-to
- Lighttpd源碼分析
- IBM Cognos Business Intelligence 10.1 Dashboarding cookbook
- Regression Analysis with Python
- Java圖像處理:基于OpenCV與JVM
- IDA Pro權威指南(第2版)
- Apache Solr PHP Integration
- Learning Jakarta Struts 1.2: a concise and practical tutorial
- Python機器學習開發(fā)實戰(zhàn)