* ngComponentOutlet-使用动态生成的组件实例的注入器

时间:2018-06-27 10:39:07

标签: angular

我有两个组件: WorldComponent ContinentComponent 。它们被安排在主模板中,如下所示:

<app-world>
  <app-continent></app-continent>
  <app-continent></app-continent>
  <app-continent></app-continent>
<app-world>

然后,在WorldComponent级别提供了一个 WorldService ,负责计算一个世界上的大洲数量。

WorldComponent使用其WorldService实例打印自己的洲数:


world.component.html

<div>
  <h2>A World</h2>
  <p>This World has {{worldService.continentCount}} continents.</p>
</div>

WorldComponent的每个子级(大洲)都注入了此服务实例,以便可以将计数增加1。


continent.component.ts (摘录)

export class ContinentComponent implements OnInit {
  constructor(private worldService: WorldService) { }

  ngOnInit() {
    this.worldService.increaseContinentCount();
  }
}

对于使用AngularJS的人来说,基本上,这是一种实现旧Angular 1.5组件的require属性的方法,而在这种情况下,子级可以注入组件级提供的服务,而无需祖先的控制器。这就是为什么我不在这里使用@Host的原因:app-continent恰好是app-world的直接子元素,但事实并非如此(想象我们想在其中计算一些<app-country>大洲而不是大洲。

到目前为止,太好了。模板

<app-world>
  <app-continent></app-continent>
  <app-continent></app-continent>
  <app-continent></app-continent>
<app-world>
<app-world>
  <app-continent></app-continent>
  <app-continent></app-continent>
<app-world>

这样渲染:


working Worlds


很抱歉,很长的介绍,现在是问题。

问题

我想通过使用Angular的*ngComponentOutlet指令以动态方式添加另一个WorldComponent,以使类似这样的事情……

<ng-container *ngComponentOutlet="WorldComponent">
  <app-continent></app-continent>
  <app-continent></app-continent>
</ng-container>

...将呈现为具有两大洲的世界。

问题在于,默认情况下,动态生成的组件将使用宿主组件的注入器,该宿主组件没有WorldService的任何提供程序。 即使有,它也将是整个应用程序范围内的单例,因此它不合适,因为每个世界显然都有其自己的洲数。

我知道*ngComponentOutlet让我们定义了一个自定义注射器,所以我们可以这样做:

<ng-container *ngComponentOutlet="WorldComponent; injector: myInjector">
  <app-continent></app-continent>
  <app-continent></app-continent>
</ng-container>

但是我现在不知道如何进行。我搜索了所有Angular文档,但是我对Angular还是很陌生,因此我无法弄清楚如何到达我们刚刚动态生成的组件的注入器,以使动态World像常规的那样工作。 / p>

export class AppComponent {
  WorldComponent = WorldComponent;
  myInjector: Injector;

  constructor() {
    //this.myInjector = ?????????
  }
}

请找到此示例的代码at this link

1 个答案:

答案 0 :(得分:2)

我在angular.io文档中发现了一些有用的信息:https://angular.io/api/common/NgComponentOutlet(也许自您发布问题以来就对其进行了添加/更新)。

在您的AppComponent构造函数中,尝试以下操作: this.myInjector = Injector.create({providers: [{provide: WorldService, deps: []}], parent: injector});