如何正确构造 angular 具有多个模块且可以相互访问的应用程序?

How to properly structure angular app with multiple modules that can access one another?

我还在习惯 Angular 以及如何正确构建不同的组件和模块。我想根据最佳实践设置我的应用程序并最大限度地提高效率。我目前有多个模块。我有一个我想导航到的“基本”模块,但根据 URL,我想合并来自其他模块的组件。这是我的应用程序-routing.module 当前的设置方式:

const routes: Routes = [
  { path: '', component: BaseComponent },
  { path: 'featureone', loadChildren: () => import('./feature-one/feature-one.module').then(m => m.FeatureOneModule) },
  { path: 'featuretwo', loadChildren: () => import('./feature-two/feature-two.module').then(m => m.FeatureTwoModule) },
  { path: '**', redirectTo: '', pathMatch: 'full'}
];

我知道此路由设置不正确,但我不确定如何以最有效的方式正确设置它。

目前,如果我导航到 '',它将按预期加载 BaseComponent。如果我添加 <app-feature-one></app-feature-one> 要么 <app-feature-two></app-feature-two> 到 BaseComponent 模板,它会抛出类似“初始化前无法访问 'FeatureOneModule'”的错误

有什么方法可以让 'featureone' 和 'featuretwo' 等路由导航到 BaseComponent,并且我可以添加逻辑来显示 <app-feature-one></app-feature-one> 要么 <app-feature-two></app-feature-two> 并且仅在导航至 'featureone' 时加载 FeatureOneModule 或在导航至 'featuretwo'?

时加载 FeatureTwoModule

因为你希望你的 BaseComponent 出现在每条路线上,你应该将它包含到你的 AppComponent 组件中:

<app-base></app-base>

如果功能组件需要显示为基础组件的兄弟,只需相应放置路由器出口即可:

<app-base></app-base>
<router-outlet></router-outlet>

如果特征组件应该嵌套到你的baseComponent的某个部分,你可以使用内容投影:

<app-base>
  <router-outlet></router-outlet>
</app-base>

然后在您的 BaseComponent 中,使用 ng-content :

<header></header>
  <ng-content></ng-content>
<footer></footer>

根据您当前的配置,因为 { path: '', component: BaseComponent }, 是第一个,所以无论您发出什么 url,它总是会解析为 BaseComponent。 Angular 通过执行 DFS 搜索来解析路由,并会 在第一个匹配处停止 ,因此您在定义路由时必须简明扼要。

解决这个问题的方法是添加 pathMatch: 'full':

{ path: '', component: BaseComponent, pathMatch: 'full' },
...

it will throw an error like "Cannot access 'FeatureOneModule' before initialization"

您收到此错误是因为 app-feature-oneapp-feature-two 是属于 lazy-loaded 模块的组件,因此,除非您 强制性地 导入那些模块,你将无法使用它们。

Is there some way where I could keep routes such as 'featureone' and 'featuretwo' ...

解决这个问题的一个快速方法是使用 named outlets:

const routes: Routes = [
  { 
    path: '', component: BaseComponent, pathMatch: 'full',
    children: [
       { path: 'featureone', loadChildren: () => import('./feature-one/feature-one.module').then(m => m.FeatureOneModule), outlet: 'feat-one' },
  { path: 'featuretwo', loadChildren: () => import('./feature-two/feature-two.module').then(m => m.FeatureTwoModule), outlet: 'feat2' },
   ]

  },
  { path: '**', redirectTo: '', pathMatch: 'full'}
];

然后,在您的 base-component.component.html

<router-outlet name="feat-one"></router-outlet>

<!-- ... -->

<router-outlet name="feat-two"></router-outlet>

为了导航到其中之一(或同时导航到两者),您必须使用如下内容:

[routerLink]="[{ outlets: { 'feat-one': 'featureone' } ... }]"