在 Angular 8 中,如何将一个组件传递给另一个组件的输入,然后在路由器模块中强制使用它

Posted

技术标签:

【中文标题】在 Angular 8 中,如何将一个组件传递给另一个组件的输入,然后在路由器模块中强制使用它【英文标题】:In Angular 8, how do I pass a component into another component's input and then use it imperatively in a router module 【发布时间】:2020-08-03 11:49:54 【问题描述】:

我已经看过以下两个线程,它们是关于在模板中使用以声明方式传入的组件(1、2、contentChildren、ng-content),我在问如何才能传入一个组件并强制使用它(在路由模块中)。

用例将用于组件库。将组件传递到包中以自动路由到并使用路由器插座显示。换句话说,我正在研究“角度 npm 包”和“角度应用程序”的接口,试图将角度组件以及其他路由设置属性从角度应用程序传递到角度 npm 包,这将用于传递信息设置路由到该组件的路由。

因此,目前,它将从使用此 app-collections 对象将特定于应用程序的数据传递到包的公共 API 开始:

@Component(
  selector: 'app-geode-app-test',
  templateUrl: './geode-app-test.component.html',
  styleUrls: ['./geode-app-test.component.scss']
)
export class GeodeAppTestComponent implements OnInit 

  environment: Environment;
  appCollections: AppCollectionInterface[];

  constructor()  

  ngOnInit() 
    this.environment = environment;
    this.appCollections = [
      
        'name': 'Short Locates',
        'routerId': 'shortLocates',
        'image': null,
        'entitlements': 'SHORT_LOCATE_READ',
        'component': ShortLocatesComponent
      ,
      
        'name': 'Short Sell Orders',
        'routerId': 'shortSellOrders',
        'image': null,
        'entitlements': 'SHORT_SELL_ORDER_READ,SHORT_SELL_ORDER_READ_MY_FUNDS',
        'component': ShortOrdersComponent
      ,
    ]
  


然后,在它的模板中,它会像这样与包交互:

<lib-geode-app [environment]="environment" [appCollections]="appCollections"></lib-geode-app>

忽略环境输入。我们专注于 appCollections 输入。

在输入输入的包的最顶层组件中,我正在将包范围的存储 OnChanges 更新为输入:

  ngOnChanges(changes: SimpleChanges): void 
    console.log('%c⧭', 'color: #00e600', changes);
    if (changes.environment.currentValue) 
      this.environmentSvc.environmentSubject.next(changes.environment.currentValue)
    

    if (changes.appCollections.currentValue) 
      console.log('%c⧭', 'color: #f2ceb6', changes.appCollections.currentValue);
      this.appCollSvc.appCollectionsSubject.next(changes.appCollections.currentValue)
    
  

这家商店运行良好,所有信息都在我需要的任何组件中成功同步:

现在,当我将它带入路由模块时,这就是事情变得混乱的地方。我希望能够将组件数据间接放入 Routes 数组中,但我似乎做不到,因为它在初始化之前已在 NgModule 元数据中使用。 因此,我正在更新 Routes 配置并在构造函数中调用的 appConfigFunction 中将这些路由转移到它上面(在模块元数据完成处理之后?)。

路由器链接正常工作并正确指向这些地址位置,但是当我单击它们时,它们会抛出此错误:

core.js:6014 ERROR 错误:未捕获(承诺中):错误:无组件 为 ShortOrdersComponent 找到工厂。你添加到 @NgModule.entryComponents?错误:找不到组件工厂 短订单组件。你把它添加到@NgModule.entryComponents 了吗? 在 noComponentFactoryError (core.js:25607) 在 CodegenComponentFactoryResolver.resolveComponentFactory (core.js:25683) 在 RouterOutlet.activateWith (router.js:8757) 在 ActivateRoutes.activateRoutes (router.js:4010) 在 router.js:3947 在 Array.forEach () 在 ActivateRoutes.activateChildRoutes (router.js:3942) 在 ActivateRoutes.activate (router.js:3805) 在 MapSubscriber.project (router.js:3778) 在 MapSubscriber._next (map.js:29) 在 resolvePromise (zone-evergreen.js:797) 在 resolvePromise (zone-evergreen.js:754) 在 zone-evergreen.js:858 在 ZoneDelegate.invokeTask (zone-evergreen.js:391) 在 Object.onInvokeTask (core.js:39680) 在 ZoneDelegate.invokeTask (zone-evergreen.js:390) 在 Zone.runTask (zone-evergreen.js:168) 在 drainMicroTaskQueue (zone-evergreen.js:559) 在 ZoneTask.invokeTask [作为调用] (zone-evergreen.js:469) 在 invokeTask (zone-evergreen.js:1603) defaultErrorLogger @ core.js:6014 handleError @ core.js:6066 next @ core.js:40558 schedulerFn@core.js:35336 __tryOrUnsub@Subscriber.js:183 下一个@Subscriber.js:122 _next@Subscriber.js:72 下一个@Subscriber.js:49 下一个@Subject.js:39 发射@core.js:35298(匿名)@core.js:39738 调用@ zone-evergreen.js:359 运行@ zone-evergreen.js:124 runOutsideAngular @ core.js:39572 onHandleError @ core.js:39735 handleError @ zone-evergreen.js:363 runGuarded @ zone-evergreen.js:137 api.microtaskDrainDone @ zone-evergreen.js:663 drainMicroTaskQueue @ zone-evergreen.js:566 invokeTask @ zone-evergreen.js:469 invokeTask @ zone-evergreen.js:1603 globalZoneAwareCallback @ zone-evergreen.js:1629

我阅读了 entryComponents 并且不确定如何将这些组件添加到包 entryComponents,但也想知道为什么我什至需要这样做,因为我通过输入成功接收了整个组件实例,正如您在上面看到的控制台日志。我还在导入(和导出以防万一有所不同)我已经在应用程序本身(在该组件模块中)中输入到包中的那个组件:

@NgModule(
  imports: [....],
  declarations: [
    ShortLocatesComponent,
    ShortOrdersComponent,
  ],
  providers: [LocatorService],
  exports: [
    ShortLocatesComponent,
    ShortOrdersComponent,
  ]
)
export class LocatorModule  

如何消除此错误并将其添加到 entryComponents 或使其不必添加到 entryComponents?

如果我可以更清楚地说明任何事情,请告诉我!

谢谢

【问题讨论】:

【参考方案1】:

通常您在路由器中定义的组件会自动添加到 entryComponents,请参阅https://angular.io/guide/entry-components

但有时您可能必须手动添加它们:

const COMPONENTS = [ShortLocatesComponent, ShortOrdersComponent];

@NgModule(
  imports: [....],
  declarations: [...COMPONENTS],
  providers: [LocatorService],
  exports: [...COMPONENTS],
  entryComponents: [...COMPONENTS]
)
export class LocatorModule  

【讨论】:

谢谢。是的,但是鉴于我的情况,我如何将它们添加到该元数据字段中?我无法导入有问题的组件,以便我可以定期将它们添加到 entryComponents,因为它们在包本身之外

以上是关于在 Angular 8 中,如何将一个组件传递给另一个组件的输入,然后在路由器模块中强制使用它的主要内容,如果未能解决你的问题,请参考以下文章

Angular5:将变量从一个组件传递到另一个打字稿文件

如何将一个反应组件传递给另一个反应组件以包含第一个组件的内容?

ReactJS - 如何将组件引用作为道具传递给另一个组件?

Angular 6:将 Observable 响应传递给另一个 Observable

React 如何将状态传递给另一个组件

如何在Angular 8中未调用的组件之间传递数据[重复]