繁体   English   中英

传入的类型不是 ComponentType,它没有 'ɵcmp' 属性。 路由未使用配置服务注入注入 AngularRouter

[英]Type passed in is not ComponentType, it does not have 'ɵcmp' property. Routing not injecting into AngularRouter using config service injection

我正在使用应用初始化程序在启动之前尝试从数据库中填充路由。 它应该非常简单,但我收到了上面的错误,我不知道为什么。 传入的类型不是 ComponentType,它没有 'ɵcmp' 属性。 它似乎绘制了路线,控制台日志实际上有回复。 只是当我单击链接或尝试直接路由到我的动态路由之一时它会失败。 在我的应用程序模块上,我还设置了入口组件,并尝试在此处设置它们以取得良好的效果,但无济于事。

Angular Info:

    Angular CLI: 11.1.4
Node: 14.7.0
OS: darwin x64

Angular: 11.1.2
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1101.4
@angular-devkit/build-angular   0.1101.4
@angular-devkit/core            11.1.4
@angular-devkit/schematics      11.1.4
@angular/cli                    11.1.4
@schematics/angular             11.1.4
@schematics/update              0.1101.4
rxjs                            6.6.3
typescript                      4.1.3

模板配置服务

 import { RouteInterface } from './../../interfaces/route.interface';
    import { HttpClient, HttpHeaders } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { map } from 'rxjs/operators';
    @Injectable({
      providedIn: 'root'
    })
    export class TemplateConfigService {
        // tslint:disable-next-line: variable-name
        private _configData ?: RouteInterface;
        // tslint:disable-next-line: variable-name
        private _promise ?: Promise<any>;
        // tslint:disable-next-line: variable-name
        private _promiseDone = false;
    
        constructor(private http: HttpClient) { }
      
    
        loadConfig(): Promise<any> {
          console.log('started')
          const url = '/assets/json/config/route.config.json';
    
          if (this._promiseDone) {
                console.log('In Config Service. Promise is already complete.');
                return Promise.resolve();
            }
    
          if (this._promise != null) {
                console.log('In Config Service. Promise exists.  Returning it.');
                return this._promise;
            }
     
          console.log('In Config Service. Loading config data.');
          this._promise = this.http
                .get(url, { headers: new HttpHeaders() }).pipe(
                // map((res: Response) => res))
                map((res: any) => {
                  res = res;
                  return res
                })
                )
                .toPromise()
                .then((res: any) => { 
                  // console.log(res)
                  this._configData = res; this._promiseDone = true; return this._configData})
                .catch((err: any) => { this._promiseDone = true; return Promise.resolve(); });
          return this._promise;
        }
     
        get configData(): any {
          console.log('should be interface', this._configData)
          return this._configData;
        }
    }

应用路由模块

 import { HomeComponent } from './components/home/home.component';
    
    import { TemplateConfigService } from './services/template-config.service';
    import { APP_INITIALIZER, Component, ComponentDecorator, ComponentFactoryResolver, Injector, NgModule, Type } from '@angular/core';
    import { Router, RouterModule, Routes } from '@angular/router';
    
    const routes: Routes = [
      {path: '', redirectTo: 'home', pathMatch: 'full'},
      {path: 'home', component: HomeComponent}
    ];
    
    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule],
      providers: [
          TemplateConfigService,
          { provide: APP_INITIALIZER, useFactory: configServiceFactory, deps: [Injector, TemplateConfigService], multi: true },
      ]
    })
    export class AppRoutingModule {
      constructor(){
      
        // console.log('data', this.configService.configData)
      }
    }
    // tslint:disable-next-line: ban-types
    export function configServiceFactory(injector: Injector, configService: TemplateConfigService): Function {
      return async () => {
          console.log('Getting config in routing module');
          const res = await configService
          .loadConfig().then((res)=>{
          res = res;
          const router: Router = injector.get(Router);
          res.forEach(
        
            (item: any) => {
            console.log(item) 
            router.config.unshift({path: item.path, component: item.comp as Type<Component>})
            console.log('router-config', router.config);
          });
          router.resetConfig(router.config);
        })
    
      };
    }

路由器接口`

import { Component } from '@angular/core';
export interface RouteInterface {
   routes: Array<[RouterInterface]>;
  }
interface RouterInterface{
    path: string;
    comp: Component;
}

`

和我的模拟 json 数据库`

[{
    "path": "one",
    "comp": "OneComponent"
},
{
    "path": "two",
    "comp": "TwoComponent"
},
{
    "path": "three",
    "comp": "ThreeComponent"
}]

`

我最终使用了一个名为 outlet 的通用组件。
`

router.config.unshift({path: path$,

                 component:
                   OutletComponent

          });

`

无论我使用什么解析器,它都不能以任何其他方式工作。 也许有一天有人可以想出一个不同的解决方法——但我不会在这上面花更多的周期,它会按照我需要的方式工作。

整个 app-routing.module.ts

    import { APP_INITIALIZER, ComponentFactoryResolver, Injector, NgModule, ViewContainerRef } from '@angular/core';
import { Router, RouterModule, Routes, ɵEmptyOutletComponent } from '@angular/router';

import { retry } from 'rxjs/operators';
import { RouterInterface } from 'src/interfaces/route.interface';

import { OutletComponent } from './components/outlet/outlet.component';
import { OutletService } from './services/outlet.service';
import { TemplateConfigService } from './services/template-config.service';

const routes: Routes = [
  {path: '', redirectTo: 'home', pathMatch: 'full'},
  {path: 'home', component: OutletComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [
      TemplateConfigService, OutletService,
      { provide: APP_INITIALIZER, useFactory: configServiceFactory, deps: [Injector, TemplateConfigService, OutletService], multi: true },
  ]
})
export class AppRoutingModule {
  constructor(private outletService: OutletService, private resolver: ComponentFactoryResolver){
    outletService.subData$.subscribe((data) => {
      data = data;
      return data;
      // sessionStorage.setItem('template', JSON.stringify(data));
    });
    // console.log('data', this.configService.configData)
  }
}
// tslint:disable-next-line: ban-types
export function configServiceFactory(injector: Injector, configService: TemplateConfigService,
                                     outletService: OutletService): any {
  return async () => {
      console.log('Getting config in routing module');
      const res = await configService
      // tslint:disable-next-line: no-shadowed-variable
      .loadConfig().then((res) => {
      res = res;
      const router: Router = injector.get(Router);
    //  const componentItem = '';
    // const instance  = this.elRef.createComponent(componentFactory, 0).instance;
    /** get and or set langkey */
      const langKey = localStorage.getItem('langKey');
      if (langKey === null) {
        localStorage.setItem('langKey', 'us-english');
        retry(2);
      }
      // tslint:disable-next-line: no-non-null-assertion
      outletService.setViewportData(langKey!);
      outletService.subData$.subscribe((data) => {
        data = data;
        return data;
        // sessionStorage.setItem('template', JSON.stringify(data));
      });

      res.forEach((item$: RouterInterface) => {
          console.log(item$);

          const path$ = item$.path;

          /** check if null or unknow and set variable langDefault */
              // tslint:disable-next-line: no-non-null-assertion
             //  outletService.headerData$.subscribe((dat: any) => {
             //   const data$ = {
             //     dat$: dat
             //   };

          router.config.unshift({path: path$,

                 component:
                   OutletComponent

          });
          console.log(router.config);

              });

      // });
      router.resetConfig(router.config);


      });

  };
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM