ng2 - 基于模板动态创建组件 [英] ng2 - dynamically creating a component based on a template

查看:23
本文介绍了ng2 - 基于模板动态创建组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究用于创建动态组件的 ComponentResolverDynamicComponentResolver 的 Angular 2 API,但我的想法与这些 API 提供的有所不同.

NG2 有没有办法根据类名的字符串创建组件?

例如,我正在构建一个可配置的图表仪表板.每个用户的布局都存储在数据库中,说明他们想要这里的 2x 折线图,那里的 3x 条形图等.

当我将此数据加载为 json 时,它看起来像:

user.charts = [{ 类型:'LineChartComponent',位置:...}{ 类型:'BarChartComponent',位置:...}];

其中 type 是我想反射性创建的组件的类名.

到目前为止,我有以下几点:

 this.chartMap = {'LineChartComponent':LineChartComponent};让 config = this.configuration;让 chartComponentType = this.chartMap[config.type];让工厂 = this.componentFactory.resolveComponentFactory(chartComponentType);让组件 = factory.create(this.injector);component.instance.configuration = config;this.chartContainer.insert(component.hostView);

但整个想法是消除对chartMap 的需要.如何在不引用类型的情况下基于字符串反射性地创建此类?

解决方案

Update2:

正如@estus 在评论版本中提到的,className 不适用于缩小.要做到与缩小一起工作,您可以

1) 在每个 entryComponents 上添加一些静态键,例如:

export LineChartComponent {静态键 = "LineChartComponent";}

然后使用这个 key 作为唯一的.

const factoryClass = >factories.find((x: any) => x.key === compClassKey);

2) 创建一个像

这样的字典

export const entryComponentsMap = {'comp1': 组件 1,'comp2':组件2,'comp3':组件 3};

然后

const factory = this.resolver.resolveComponentFactory(entryComponentsMap.comp1);

更新 1:

这是来自组件类名的版本

const factory = Array.from(this.resolver['_factories'].keys());const factoryClass = <Type<any>>factories.find((x: any) => x.name === compClassName);const factory = this.resolver.resolveComponentFactory(factoryClass);

旧版本

您可以通过组件选择器获取工厂,但您必须使用私有属性.

它可能看起来像:

const factory = Array.from(this.resolver['_factories'].values());const factory = factory.find((x: any) => x.selector === selector);

Plunker 示例

I've been looking at the Angular 2 APIs for ComponentResolver and DynamicComponentResolver for creating dynamic components, but I have something different in mind than those APIs offer.

Is there any way in NG2 to create a component based on a string of its class name?

For example, Im building a configurable charts dashboard. Each user's layout is stored in the database, stating they want 2x line charts here, 3x bar charts there, etc.

When I load this data as json it looks something like:

user.charts = [
     { type: 'LineChartComponent', position: ... }
     { type: 'BarChartComponent', position: ... }
];

Where type is the component's class name that I want to reflectively create.

So far I have the following:

 this.chartMap = {
    'LineChartComponent': LineChartComponent
 };

let config = this.configuration;
let chartComponentType = this.chartMap[config.type];
let factory = this.componentFactory.resolveComponentFactory(chartComponentType);
let component = factory.create(this.injector);
component.instance.configuration = config;
this.chartContainer.insert(component.hostView);

But the whole idea is to eliminate the need for chartMap. How can I reflectively create this class based on a string without having a reference to the type?

解决方案

Update2:

As @estus mentioned in comments version with className won't work with minification. To do it working with minification you can

1) add some static key on each of your entryComponents like:

export LineChartComponent {
  static key = "LineChartComponent";
}

and then use this key as unique.

const factoryClass = <Type<any>>factories.find((x: any) => x.key === compClassKey);

2) create a dictionary like

export const entryComponentsMap = {
  'comp1': Component1,
  'comp2': Component2,
  'comp3': Component3
};

and then

const factory = this.resolver.resolveComponentFactory(entryComponentsMap.comp1);

Update1:

Here's version from component`s class name

const factories = Array.from(this.resolver['_factories'].keys());
const factoryClass = <Type<any>>factories.find((x: any) => x.name === compClassName);
const factory = this.resolver.resolveComponentFactory(factoryClass);

Old version

You can get factory by component selector but you have to use private property.

It might look something like:

const factories = Array.from(this.resolver['_factories'].values());
const factory = factories.find((x: any) => x.selector === selector);

Plunker Example

这篇关于ng2 - 基于模板动态创建组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆