在逻辑组件树中创建具有不同位置的动态组件 app.tokens.ts app.module.ts app.component.ts foo.component.ts

我希望构建一个组件,该组件使用Angular的componentFactoryResolvercomponentFactory将组件动态注入到DOM上,但使用传入的viewContainerRef来确定可用于注入的内容。

@Component({
  selector: 'my-component-loader',template: ``
})
export class MyComponentLoader implements OnInit  {

  constructor(private viewContainerRef: ViewContainerRef,private componentFactoryResolver: ComponentFactoryResolver,private componentLoaderService: ComponentLoaderService) {
  }

  ngOnInit() {
      this.componentLoaderService.loadComponent.pipe(
        tap((component,componentViewContainerRef) => this.loadComponent(component,componentViewContainerRef))
      ).subscribe();
  }

  loadComponent(component,callerViewContainerRef) {
    this.viewContainerRef.clear();

    const factory = this.componentFactoryResolver.resolveComponentFactory(component);
    this.viewContainerRef.createComponent(factory);
  }
}

如何使用my-component-loader的逻辑位置在callerViewContainerRef位置内加载组件,以便创建的组件具有可用于callerViewContainerRef的DI树。

简而言之,这类似于Material的MatDialog。

https://github.com/angular/components/blob/master/src/material/dialog/dialog-config.ts

有没有更简单的方法来处理而不复制Angular cdk门户逻辑?

**编辑**

这和传递callerViewContainerRef的注入器一样简单吗?

this.viewContainerRef.createComponent(factory,callerViewContainerRef.injector);
harry898 回答:在逻辑组件树中创建具有不同位置的动态组件 app.tokens.ts app.module.ts app.component.ts foo.component.ts

  

这和传递callerViewContainerRef的注入器一样简单吗?

我认为这是正确的。这是我的另一个示例,它使我有了更好的理解。

app.tokens.ts

export const FooToken = new InjectionToken('foo');

app.module.ts

@NgModule({
 /* ... */
 providers: [
  {
   provide: FooToken,useValue: { message: 'default foo value' }
  }
 ]
})
export class AppModule { }

app.component.ts

@Component({
  selector: 'my-app',template: `
    <ng-container #vcr></ng-container>
  `,styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  @ViewChild('vcr',{ static: true,read: ViewContainerRef })
  vcr: ViewContainerRef;

  ngAfterViewInit () {
    const compFactory = this.cfr.resolveComponentFactory(FooComp);

    const inj = Injector.create({
      providers: [
        {
          provide: FooToken,useValue: { message: 'this is just a foo message from a dynamic injector!' }
        }
      ]
    })

    this.vcr.createComponent(compFactory,inj); 
  }
}

foo.component.ts

@Component({
  selector: 'foo',template: `Foo!!`
})
export class FooComp {
  constructor (@Inject(FooToken) private fooToken) {
    console.log('[FOO]',this.fooToken)
  }
}

如果按原样运行代码,则应该在Foo的构造函数中看到{ message: 'this is just a foo message from a dynamic injector!' }

但是,如果您在创建组件时未指定自定义注射器

this.vcr.createComponent(compFactory);

您应该看到以下内容:{ message: 'default foo value' }

您可以在我的playground中找到上述想法。

本文链接:https://www.f2er.com/3169336.html

大家都在问