gpt4 book ai didi

angular - 如何注入(inject)动态创建的组件的服务

转载 作者:行者123 更新时间:2023-12-02 18:48:09 24 4
gpt4 key购买 nike

export interface InfoPanelComponent {
data: any;
}

export class ComplaintsComponent implements OnInit, InfoPanelComponent {
data: any;
constructor(private navigationService: NavigationService, private activatedRoute: ActivatedRoute) {
}

onCancelClicked() {
console.log(this.navigationService);
this.navigationService.hidePanel(this.data.key, this.activatedRoute);
}
}

问题是,this.navigationService 未定义。服务本身在app.modules.ts中提供,并且可以成功注入(inject)到其他组件中。

我认为它不起作用的原因是上面的组件(以及将来的更多组件)是动态创建的:

private addPanel(item: InfoPanelItem, itemKey: string): void {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(item.component);
const viewContainerRef = this.infopanelHost.viewContainerRef;

// create new component
const componentRef = viewContainerRef.createComponent(componentFactory);

(<InfoPanelComponent>componentRef.instance).data = item.data;
}

我认为因此服务没有被注入(inject)。有没有一种方法可以普遍注入(inject)组件所需的所有依赖项?请注意,ComplaintsComponent 只是一个示例, future 还会有更多示例,可能需要不同的服务。

最佳答案

您可以通过这两种方式为您的动态组件提供服务。在我的示例中,我将演示在容器组件 DynamicContainerComponent 内创建组件。

首先在容器组件中导入您需要的所有服务。在我的示例中 AExampleServiceBExampleService

动态容器组件

import {
Component, ViewChild, AfterContentInit, ComponentFactoryResolver, Compiler, ViewContainerRef, NgModule, NgModuleRef,
} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AExampleService } from './services/AExampleService';
import { BExampleService } from './services/BExampleService';


@Component({
selector: 'dynamic-container',
template: `<ng-container #vc></ng-container>`,
styleUrls: ['./dynamic-container.component.css']
})
export class DynamicContainerComponent implements AfterContentInit{
@ViewChild('vc', { read: ViewContainerRef }) _container: ViewContainerRef;

constructor(private aExampleService: AExampleService) { }

ngAfterContentInit(){
this.addDynamicComponent();
}

private addDynamicComponent(): void{...}
}

现在您可以通过在动态组件中使用依赖项注入(inject)来使用AExampleServiceBExampleService。此示例展示了两种方法:

  • 将服务 BExampleService 直接 DI 到动态组件中
  • 将父组件 DynamicContainerComponent 注入(inject)将公开 AExampleService动态组件

看一下private addDynamicComponent(): void{...}中的代码

addDynamicComponent()

private addDynamicComponent(): void{

@Component({
template: `<h2>This is a dynamic component</h2>`,
styleUrls: ['./dynamic.component.css']
})
class DynamicComponent {
constructor(
public _parent: DynamicContainerComponent,
private bExampleService: BExampleService) { }

private someFunctionA(): void {
this._parent.aExampleService.doSomthingA();
}

private someFunctionB(): void {
this.bExampleService.doSomthingB();
}
}
@NgModule({
imports: [
BrowserModule
],
declarations: [DynamicComponent],
}) class DynamicModule { }

const mod = this.compiler.compileModuleAndAllComponentsSync(DynamicModule);
const factory = mod.componentFactories.find((comp) =>
comp.componentType === DynamicComponent
);

this.cmpRef = this._container.createComponent(factory);
}

请注意,AExampleServiceBExampleService 均未声明为动态组件的提供者,而是将它们声明为包含以下内容的模块的提供者: DynamicContainerComponent

关于angular - 如何注入(inject)动态创建的组件的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49386488/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com