在Angular 5 +

时间:2018-04-13 14:27:34

标签: angular typescript angular5 angular2-components

迁移到Angular v.5.2.9后发现了弃用消息:

  

不推荐使用ReflectiveInjector:从v5开始 - 缓慢并带来大量代码,改为使用Injector.create

在Angular v5之前,我创建了这样的动态组件:

ReflectiveInjector

// Old API with ReflectiveInjector
createWithReflectiveInjector() {
  // Inputs need to be in the following format to be resolved properly
  const resolvedInputs = ReflectiveInjector.resolve([
  { provide: "options", useValue: this.data }
  ]);

  // Clear the template before inserting new one
  this.dynamicComponentContainer.clear();

  // We create an injector out of the data we want to pass down and this components injector
  const injector = ReflectiveInjector.fromResolvedProviders(
    resolvedInputs,
    this.dynamicComponentContainer.parentInjector
  );

  // We create a factory out of the component we want to create
  const factory = this.resolver.resolveComponentFactory(CounterWithInject);

  // We create the component using the factory and the injector
  const component = factory.create(injector);

  // Subscribe to Output events:
  component.instance.resetCounter.subscribe(() => {
    this.data.count = 0;
  });

  // We insert the component into the dom container
  this.dynamicComponentContainer.insert(component.hostView);
}  

我已经使用 Injector.create()重构了更新的API:

注射器

createWithInjector() {
  const inputs = [{ provide: "options", useValue: this.data }];

  // Clear the template before inserting new one
  this.dynamicComponentContainer2.clear();

  const injector = Injector.create({
    providers: inputs,
    parent: this.dynamicComponentContainer2.parentInjector
  });

  // We create a factory out of the component we want to create
  const factory = this.resolver.resolveComponentFactory(CounterWithInput);

  // Destroy the previously created component
  if (this.componentRef) {
    this.componentRef.destroy();
  }

  this.componentRef = this.dynamicComponentContainer2.createComponent(
  factory, 0, injector);

  // We insert the component into the dom container
  this.dynamicComponentContainer2.insert(this.componentRef.hostView);

  this.componentRef.instance.resetCounter.subscribe(() => {
    this.data.count = 0;
  });
}  

即使在切换到新的Injector API之后,它实际上也是相同的代码。

我的问题是:
1)也许我在文档中遗漏了一些东西,并且在Angular v5 +中可以大大简化创建动态组件? 2)注意到在official doc输入数据中提供了组件的扩展实例,如下所示:

let componentRef = viewContainerRef.createComponent(componentFactory);
(<AdComponent>componentRef.instance).data = adItem.data; 

为动态组件提供道具的首选方式:
与提供商

const inputs = [{ provide: "options", useValue: { count: 0} }];
const injector = Injector.create({
  providers: inputs,
  parent: this.dynamicComponentContainer2.parentInjector
});

并阅读组件中注入的道具:

...
ngOnInit() {
  this.options = this.injector.get("options") || {};
}

实例扩展

// Define input data
this.componentRef.instance.data = { count: 0 }; 

并在组件中获取 @Input()

export class CounterWithInput implements OnInit {
  @Input() data: any;
}

使用方法进行现场演示:link

1 个答案:

答案 0 :(得分:0)

我在这里做了一些动态组件注入的演示 DEMO