【问题标题】:Angular Dynamic ROuting and Lazy loading角动态路由和延迟加载
【发布时间】:2018-07-06 08:04:07
【问题描述】:

我正在尝试从数据库动态创建我的 Angular 路由。 我以某种方式实现了它。

我也关注了 AppIntializer。

App.module.ts ....

providers:[...{
        provide: APP_INITIALIZER,
        useFactory: AppInitializerFn,
        multi: true,
        deps: [AppConfigService,RouteConfigService]
      }...]


  export const AppInitializerFn = (
    appConfig: AppConfigService,
    routeConfigService:RouteConfigService) => {
    return () => {
      return appConfig.loadAppConfig().then(()=>{
        return  routeConfigService.configure();
      });
    };
  };

 configure() {
    appRoutes[1].children= [];
    return this.http.get('/assets/data/menu.json').toPromise()
    .then((data:Array<any>) => {

      data.forEach((x:any)=>{
        appRoutes[1].children.push({path:x.path,
          loadChildren: this.appConfig.getConfig().AppSpecificComponentURL+x.compPath
        });

      });

      var router: Router = this.injector.get(Router);
      router.resetConfig(appRoutes);
      console.log(appRoutes)
    });
  }

menu.json

 [
          { "path": "dashboard", "compPath":"dashboard/dashboard.module#DashboardModule","default":true},
          { "path": "customer", "compPath":"customer/customer.module#CustomerModule"},
          { "path": "employee", "compPath":"employee/employee.module#EmployeeModule"},
          { "path": "supplier", "compPath":"supplier/supplier.module#SupplierModule"}
    ]

现在的问题是延迟加载的模块甚至没有编译,因此出现错误 “找不到模块”./src/app/app-specific/employee/employee.module”

任何帮助表示赞赏。

【问题讨论】:

  • 我的问题是——如何在动态路由的情况下编译延迟加载的模块

标签: angular routing angular6 dynamic-routing


【解决方案1】:

我找到了一个简单的解决方案。这个对我有用。我希望能帮助别人。

在 pages.routing.module.ts 中

import { NgModule } from '@angular/core';
import { Routes, RouterModule, Router } from '@angular/router';

import { DataService } from '@services/data-service.service';

import { DashboardComponent } from '../dashboard/dashboard.component';

import { ContactsComponent } from './contacts/contacts.component';
import { TaxDataComponent } from './tax-data/tax-data.component';
import { LocalsComponent } from './locals/locals.component';
import { ChildrenItem } from '@app/models/children-item.model';
import { AuthorisedLayoutComponent } from '@app/layout/authorised/authorised-layout/authorised-layout.component';
import { AddressesComponent } from './addresses/addresses.component';

const appRoutes: Routes = [
  {
    path: '',
    component: AuthorisedLayoutComponent,
    children: [ ],
  },
];

const components = {
  dashboardComponent: DashboardComponent,
  addressesComponent: AddressesComponent,
  contactsComponent: ContactsComponent,
  taxDataComponent: TaxDataComponent,
  localsComponent: LocalsComponent,
};

@NgModule({
  imports: [RouterModule.forChild(appRoutes)],
  exports: [RouterModule]
})
export class PagesRoutingModule {

  constructor(private dataService: DataService, private router: Router) {
    this.dataService.getMenu().subscribe(
      (menu: any) => {
        this.dataService.user.menu = menu;

        const customRoutes = [];

        const key = 'main';
        if (this.dataService && this.dataService.user && menu
          && menu.navigation && menu.navigation[key]) {

          menu.navigation[key].map((x: any) => {
            const el: any = {};
            el.path = x.path;
            if (x.children) {
              el.children = [];
              x.children.forEach((child: ChildrenItem) => {
                if (!components[child.component]) {
                  console.error(`Component: ${child.component} doesn't exists!`);
                }
                el.children.push({
                  path: child.path,
                  component: components[child.component]
                });
              });
            }
            if (x.pathMatch) {
              el.pathMatch = x.pathMatch;
            }
            if (x.component) {
              if (!components[x.component]) {
                console.error(`Component: ${x.component} doesn't exists!`);
              }
              el.component = components[x.component];
            }
            if (x.redirectTo) {
              el.redirectTo = x.redirectTo;
            }
            if (x.canActivateChild) {
              el.canActivateChild = [components[x.canActivateChild]];
            }
            customRoutes.push(el);
          });
        }

        customRoutes.forEach((x: any) => appRoutes[0].children.push(x));

        this.router.config.forEach((child: any) => {
          if (child.path === 'pages' && child._loadedConfig) {
            child._loadedConfig.routes.forEach((x: any) => {
              if (x.path === '') {
                x.children = customRoutes;
              }
            });
          }
        });

        RouterModule.forChild(appRoutes);
      }, error => console.log(error)
    );

  }
}

服务器的响应是这样的:

{
    user: {
      name: 'crivero',
      roles: ['admin']
    },
    navigation: {
      main: [
        { path: 'dashboard', component: 'dashboardComponent' },
        { path: 'addresses-app', component: 'addressesComponent' },
        { path: 'contacts-app', component: 'contactsComponent' },
        { path: 'tax-data-app', component: 'taxDataComponent' },
        { path: 'locals-app', component: 'localsComponent' },
      ],
      basePlatform: [
        { path: 'contactos', pathMatch: 'full', redirectTo: 'contactos/list' },
        {
          path: 'contactos',
          canActivateChild: 'authGuardService',
          children: [
            {
              path: 'list',
              component: 'contactsListComponent',
              data: {}
            }, {
              path: 'new',
              component: 'contactsNewComponent',
              data: {}
            }, {
              path: ':id/edit',
              component: 'contactsEditComponent',
              data: {}
            },
          ],
          data: { roles: [] }
        },          
      ],
    },
    menus: {
      main: [
        { name: 'Inicio', link: '/pages/dashboard' },
        { name: 'Direcciones', link: '/pages/addresses-app' },
        { name: 'Contactos', link: '/pages/contacts-app' },
        { name: 'Datos fiscales', link: '/pages/tax-data-app' },
        { name: 'Locales', link: '/pages/locals-app' },
      ],
      basePlatform: [
      ]
    }
}

data-service.service.ts

  getMenu() {
    return this.httpClient.get(config.baseUrl + config.apiGetMenu,
      { headers: this.getHeaders() }).pipe(
        map((response: NavigationMenu) => {
          // return response;
          return customMenuMock;
        }),
        catchError((error: Response) => {
          return throwError('Fail to get data from server');
        },
        ),
      );
  }

【讨论】:

    【解决方案2】:

    这不是配置动态路由的正确方法。从 app.module.ts 调用 http 请求就像杀死 Angular;您应该首先在服务文件中订阅动态菜单。然后您将获得这样的数据 [ { “路径”:“仪表板”,“compPath”:“dashboard/dashboard.module#DashboardModule”,“default”:true}, {“路径”:“客户”,“compPath”:“客户/客户.模块#客户模块”}, { “路径”:“雇员”,“compPath”:“雇员/雇员.module#EmployeeModule”}, {“路径”:“供应商”,“compPath”:“供应商/供应商.module#SupplierModule”} ];

    let x = selected Array;
    
    let appRoutes = [];
     x.forEach(val => {
          appRoutes.push({
              path: val.path,
              loadChildren: val.compPath
          };
      });
    

    然后像这样导入 - app.module.ts 中的 RouterModule.forRoot(AppRoutes)

    这只是工作流程的一个简单概念。希望你明白。 在 Angular 中使用 Promise 也不是最佳做法;

    【讨论】:

    • AppInitializer 目前仅支持 Promise。其次,如果我不在应用程序初始化程序中进行 http 调用,将如何创建动态路由。
    猜你喜欢
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 2015-03-28
    • 2020-07-12
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多