角动态路由和延迟加载

时间:2018-07-06 08:04:07

标签: angular routing angular6 dynamic-routing

我正在尝试从数据库动态创建我的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”

任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:0)

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

在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');
        },
        ),
      );
  }

答案 1 :(得分:-1)

这不是配置动态路由的正确方法。从app.module.ts调用http请求就像杀死Angular一样;您应该先在服务文件中订阅动态菜单,然后您将获得类似这样的数据  [           {“ path”:“ dashboard”,“ compPath”:“ dashboard / dashboard.module#DashboardModule”,“ default”:true},           {“ path”:“ customer”,“ compPath”:“ customer / customer.module#CustomerModule”},           {“ path”:“ employee”,“ compPath”:“ employee / employee.module#EmployeeModule”},           {“ path”:“供应商”,“ compPath”:“ supplier / supplier.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)

这只是工作流程的一个基本概念。希望你能理解。 同样,在角度上使用promise不是最佳实践;