从angular2中的字符串解析组件的类型<>

Leo*_*Bor 7 typescript angular

是否有可能Type<T>string值获取component()的类型?Smth喜欢:

let typeStr: string = 'MyComponent';
let type: any = resolveType(typeStr); // actual type
Run Code Online (Sandbox Code Playgroud)

Nit*_*mer 8

如果不为类保留"注册表",则无法做到这一点.

interface Component { }

type ComponentClass = { new (): Component };

const REGISTRY = new Map<string, ComponentClass>();

function getTypeFor(name: string): ComponentClass {
    return REGISTRY.get(name);
}
Run Code Online (Sandbox Code Playgroud)

至于如何添加条目REGISTRY,你有几个选项,这里有两个:

(1)在每个类定义后手动添加:

class ComponentA implements Component { ... }
REGISTRY.set("ComponentA", ComponentA);
Run Code Online (Sandbox Code Playgroud)

或者为它做一个功能:

function register(cls: ComponentClass): void {
    REGISTRY.set(cls.name, cls);
}

class ComponentA implements Component { ... }
register(ComponentA);
Run Code Online (Sandbox Code Playgroud)

(2)使用装饰器:
只需使用上面的register函数作为装饰器:

@register
class ComponentA implements Component { ... }
Run Code Online (Sandbox Code Playgroud)

  • 当我在我的项目中实现这个时,我不得不面对另一个问题.我的组件有构造函数,它们使用不同的输入参数.然后编译器说我不能使用`register`装饰器.因为该组件与`ComponentClass`不兼容.你有什么想法如何处理? (2认同)

小智 6

以防万一有人像我一样偶然发现这个问题。无需维护注册表即可实现。

完全归功于yurzui 的解决方案

只是从那里复制:

import { Type } from '@angular/core';

@Input() comp: string;
...
const factories = Array.from(this.resolver['_factories'].keys());
const factoryClass = <Type<any>>factories.find((x: any) => x.name === this.comp);
const factory = this.resolver.resolveComponentFactory(factoryClass);
const compRef = this.vcRef.createComponent(factory);
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,这在 Angular 9 中不再有效,因为他们从 CFR 中删除了“_factories”。也就是说,无论如何,最好远离私人道具! (3认同)