1

我有两个组件:WorldComponentContinentComponent。它们排列在主模板中,如下所示:

<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。


大陆.component.ts(摘录)

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

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

对于使用过 AngularJS 的人来说,基本上这是一种实现require旧 Angular 1.5 组件属性的方法,而在这种情况下,子组件会获得组件级提供的服务,而不是需要祖先的控制器。这就是我不在@Host这里使用的原因:app-continent恰好是的直接孩子,app-world但不可能是这种情况(想象我们想<app-country>在大洲而不是大洲内计算一些 s)。

到现在为止还挺好。模板

<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>

呈现如下:


工作世界


抱歉介绍了这么长,现在问题来了。

问题

我想通过使用 Angular 的指令以动态方式添加另一个 WorldComponent *ngComponentOutlet,这样就可以了......

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

...将呈现为一个拥有 2 个大陆的世界。

问题是,默认情况下,动态生成的组件将使用宿主组件的注入器,它没有任何 WorldService 提供者。就算有,那也是应用范围的单例,所以不合适,因为每个世界显然都有自己的大陆数。

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

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

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

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

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

请在此链接中找到此示例的代码。

4

1 回答 1

2

我在 angular.io 文档中找到了一些有用的信息:https ://angular.io/api/common/NgComponentOutlet (可能是在发布您的问题后添加/更新的)。

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

于 2019-11-25T20:45:26.107 回答