在 Angular 的嵌套路由器出口中动态加载模块

syn*_*ror 5 angular-routing angular angular-router

我有一个 Angular 5 应用程序,它可以动态加载功能模块并在主路由器插座中显示它们的内容。下面的代码显示了我的基本配置:

来自根模块(主路由器插座)的 app.component:

<router-outlet></router-outlet>
Run Code Online (Sandbox Code Playgroud)

root 的路由配置(模块从传递的 url 动态加载):

const routes: Routes = [
    { path: 'module1', loadChildren: ...},
    { path: 'module2', loadChildren: ...}
];

export const AppRoutes = RouterModule.forRoot(routes);
Run Code Online (Sandbox Code Playgroud)

功能模块之一的示例路由:

const routes: Routes = [
    { path: 'report/:reportId', component: ReportComponent}
];

export const AppRoutes = RouterModule.forChild(routes);
Run Code Online (Sandbox Code Playgroud)

及其包含另一个路由器插座的 app.component :

<router-outlet></router-outlet>
Run Code Online (Sandbox Code Playgroud)

这样的配置工作正常 - 如果我去 mysite.com/module1,然后加载 module1 并且 angular 控制功能模块路由器,所以访问 mysite.com/module1/report/2 会在功能模块的路由器出口内显示 ReportComponent。

我现在要做的是将 TabsComponent 添加到我的主模块中,以便能够从多个选项卡组合页面,其中每个选项卡将包含一个特定模块。我想以某种方式为 root 使用已经指定的路由,而无需手动将其重复为 TabsComponent 的子项,并将功能模块加载到 TabsComponent 的路由器插座中。

tabs.component:

<tabs-navigation></tabs-navigation>
<router-outlet></router-outlet>
Run Code Online (Sandbox Code Playgroud)

tabs.configuration(在运行时通过 http 动态加载):

{
    pageId: "page1",
    tabs: [{
        tabId: "tab1",
        module: "module1",
        params: "report/2"
    }, {
        tabId: "tab2",
        module: "module2"
    }]
}
Run Code Online (Sandbox Code Playgroud)

以及我的 root 路由配置中的附加行:

{ path: 'tabs/:pageId', component: TabsComponent}
Run Code Online (Sandbox Code Playgroud)

从现在开始访问 mysite.com/tabs/page1 时,我想:

  1. 通过 http 端点读取 page1 的配置。
  2. 生成指向该页面所有已配置选项卡的链接作为选项卡导航。
  3. 单击链接后,在 TabsComponent 的路由器出口内显示选项卡的内容(默认情况下应显示第一个选项卡)。它基本上意味着将功能模块加载到该路由器插座而不是主插座。

我的两个问题是:

  1. 如果我希望将所有功能模块作为独立页面(因为它们现在工作)或作为选项卡式页面中的选项卡加载,则如何正确配置路由。
  2. 如何为选项卡式场景生成链接,以便我可以通过导航或直接从给定的 url 转到特定选项卡?我想我需要同时包含页面和标签 ID 以及模块详细信息才能使所有部分正常工作,例如 mysite.com/page1/tab1/module1/report/2。

小智 0

@syntax_error 这就是我的做法。我对 Angular 也有类似的要求。我的应用程序有一个显示多个用户的页面,每个用户都有相应的详细视图/路线。例如

  • 用户列表页面列出用户 A、B、C
  • 用户A的信息
    • 用户A的家庭信息
    • 用户A所在城市家庭信息
    • 用户A的国家/地区家庭信息
  • 用户A的办公室信息

用户 A 的信息也有子状态(家庭信息、城市信息、乡村家庭都是用户 A 信息的子路由)大多数顶级路由都是这种情况。我使用 ngrx 和 mat-tab 来解决我的问题。外壳组件如下对齐。

<header></header>
<my-tab></my-tab>
<router-outlet></router-outlet>
<footer></footer>
Run Code Online (Sandbox Code Playgroud)

my-tab 组件负责监听每当选项卡列表更新时触发的可观察对象。每当可观察对象获得响应时,选项卡组件就会呈现更新的选项卡。单个选项卡表示为

{
 id: unique tab id,
 isActive: is tab current active,
 isHomeTab: denotes if a tab is home tab or user tab
 currentViewURL: current route url for this tab
 timestamp: time in ms when this tab was created //used to decide the order in which tabs are created
}
Run Code Online (Sandbox Code Playgroud)

流程如下,

  1. 应用程序引导程序和 ngrx 加载默认选项卡。对于默认选项卡,当前视图 url 为空
  2. 创建新选项卡后,副作用将通过路由到选项卡中存储的状态来启动该选项卡。对于默认选项卡,其空和空 url 已映射到主状态,因此在路由器出口中主路由被激活。
  3. 现在,当最终用户从用户列表中选择新用户时,将创建一个新选项卡并将其添加到状态中。该路由指向信息的默认路由,该选项卡的 isActive 设置为 true,而其他选项卡的 isActive 设置为 false。添加选项卡以说明步骤 2 中提到的副作用会通过读取当前视图 url 并导航到该选项卡来激活该选项卡。
  4. 创建选项卡后,选项卡可观察对象会更新,这会触发选项卡组件中的侦听器,然后根据新列表重新呈现选项卡。
  5. 要维护选项卡的路由器状态,请侦听路线导航完成事件,然后找出当前活动选项卡并更新其当前视图 url。
  6. 每当单击现有选项卡时,读取选项卡 URL 并导航到该选项卡。
  7. 每当单击选项卡关闭时,都会将该选项卡从状态中删除。这将触发一个效果,然后使用时间戳属性查找在此选项卡之前创建的选项卡。找到选项卡后,它将使用当前视图 url 属性导航到该选项卡。

希望这可以帮助您或其他人决定如何继续实施选项卡。