msa*_*ord 5 typescript router-outlet angular
我有一个延迟加载的多模块 Angular 7.2.2 应用程序,它似乎AppComponent在自身内部创建 main 模板的副本,然后在其中渲染路由组件。
这是我对完整但简洁的序言的尝试(我无法在 plunkr 中重现这一点)。请询问我遗漏的任何细节。
我有一个index.html包含普通 HTML 的文件,以及<app-root>其<body>. 这是项目中唯一app-root出现标签的位置。angular.json该文件在的属性中引用projects.app.architect.build.options.index。
主要AppComponent声明为
@Component({
selector: 'app-root',
template: `
<router-outlet></router-outlet>
<message-banner [show]="showMessage" [message]="message"></message-banner>
`,
providers: [AuthenticationService, AuthenticationGuard, MessagingService]
})
Run Code Online (Sandbox Code Playgroud)
其余逻辑AppComponent只是调解应用程序范围通知的内容show。message我没有路由器出口挂钩,也没有直接的 DOM 操作。
我main.ts像往常一样引导应用程序
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
import { environment } from './environments/environment';
import { hmrBootstrap } from './hmr';
if (environment.production) {
enableProdMode();
}
const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule);
if (environment.hmr && module['hot']) {
hmrBootstrap(module, bootstrap);
}
else {
bootstrap().catch(err => console.log(err));
}
Run Code Online (Sandbox Code Playgroud)
从以下AppModule
@NgModule({
imports: [
appRoutes,
BrowserAnimationsModule,
BrowserModule,
CommonModule,
FormsModule,
HttpClientModule,
HttpClientXsrfModule,
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
SharedGenericModule
],
declarations: [
AppComponent,
MessageBannerComponent
],
providers: [
{ provide: APP_BASE_HREF, useValue: '/' },
appRoutingProviders,
ChoosePasswordGuard,
LoadingBarService,
Title,
UserService
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
bootstrap: [AppComponent]
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
使用这些app.routes(小摘录)
const routes: Routes = [
{
path: '',
redirectTo: 'shop',
pathMatch: 'full'
},
{
path: '',
component: AppComponent,
children: [
{
path: 'shop',
data: { key: 'shop' },
loadChildren: "./modules/shop.module#ShopModule",
pathMatch: 'full'
},
{
path: 'car/:id',
data: { key: 'car' },
loadChildren: "./modules/car.module#CarModule",
pathMatch: 'full'
},
{
// This one has child routes, which I will add if needed
path: 'workOrder',
data: { key: 'workOrder' },
loadChildren: "./modules/workOrder.module#WorkOrderModule",
}
// And many more
]
}
]
export const appRoutes: ModuleWithProviders = RouterModule.forRoot(routes, {
enableTracing: false,
onSameUrlNavigation: 'reload'
});
Run Code Online (Sandbox Code Playgroud)
一旦应用程序稳定下来,生成的 DOM 如下所示:
<body>
<app-root ng-version="7.2.2">
<router-outlet></router-outlet>
<app-root>
<router-outlet></router-outlet>
<default-routed-component _nghost-c0>...</default-routed-component>
<message-banner ng-reflect-show="true" ng-reflect-message="[object Object]">...</message-banner>
</app-root>
<message-banner ng-reflect-show="true" ng-reflect-message="[object Object]">...</message-banner>
</app-root>
</body>
Run Code Online (Sandbox Code Playgroud)
请注意,内部<app-root>没有用 装饰ng-version。
另外,我只能以编程方式与内部进行通信<message-banner>,外部似乎已断开连接。但是在加载第一个路由之前(在应用程序稳定之前)生成的消息将发送到消息横幅的两个实例。
为什么我的应用程序用两个实例化两个<app-root>s <router-outlets>,但只使用其中之一。我怎样才能阻止它这样做?
我需要在应用程序范围内保留一个<message-banner>,但我显然想要一个。如果不是该组件的重复,这可能只是一种神秘的不便 - 该应用程序在其他方面都运行得很好。
回想起来,答案是极其明显的。
主AppComponent(包含<router-outlet>我想在整个应用程序中使用的应用程序的唯一通用代码)是从主 AppModule 引导的,并由Router 作为默认路由的组件第二次实例化,然后将功能模块加载为子路由。
解决方法只是删除 AppComponent 和子路由;所以app.routes.ts要从
const routes: Routes = [
{
path: '',
redirectTo: 'shop',
pathMatch: 'full'
},
{
path: '',
component: AppComponent,
children: [
{
path: 'shop',
data: { key: 'shop' },
loadChildren: "./modules/shop.module#ShopModule",
pathMatch: 'full'
},
...
}
]
Run Code Online (Sandbox Code Playgroud)
到
const routes: Routes = [
{
path: '',
redirectTo: 'shop',
pathMatch: 'full'
},
{
path: 'shop',
data: { key: 'shop' },
loadChildren: "./modules/shop.module#ShopModule",
pathMatch: 'full'
},
...
]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19368 次 |
| 最近记录: |