根据类名创建类的实例 : 字符串

7

在任何人标记此问题为重复之前,请阅读以下内容:

我的情况不仅涉及TypeScript,还涉及Angular2

目标

我需要一个在app.component.ts中的方法,该方法接受一个字符串(类名)并创建该类的实例。这些类存在于其他ts文件中。

现在来看使用情况: 我有一个方法getWidgetObjectFromClassName(className : string) : Object{} ,它需要返回以字符串格式表示的类名称的实例。现在问题来了,

我尝试使用NameSpace, 并执行let instance = new SampleNS['OtherName'](); (SampleNS是一个namespace),在单个文件的情况下可以正常工作。

但是现在我有多个ts文件,比如interfaces.ts,classes.ts,otherclasses.ts。我在interface.ts中使用export namespace SampleNS{},然后在classes.ts中使用///<reference path="interfaces.ts" />和相同的命名空间 SampleNS

现在我的方法getWidgetObjectFromClassName(className : string) : Object{}在xyz.ts中,现在应该给出哪个import呢?我的意思是,如果我说'import {SampleNS} from './interfaces'。 问题在于我只能导入一个文件的命名空间(即使它是相同的),因此我创建的实例仅限于特定文件命名空间的导入。

Plunker链接 https://plnkr.co/edit/pt90F34KPsGoHDpSUQFD?p=preview


创建一个文件,导出所有组件,然后只需使用命名空间导入此文件,就可以以相同的方式引用所有组件了,这个方法怎么样? - Günter Zöchbauer
3
请注意,为避免重复,请先阅读以下内容。- 不,我更喜欢掷硬币来判断是否存在重复。 - nnnnnn
好的,Gunter... 我会试一下你的解决方案,有进展会回复你的。 - Pratik Kelwalkar
@GünterZöchbauer 即使我这么做,它也无法定位类,我应该发布一个 plunker 吗? - Pratik Kelwalkar
Plunker会很棒。 - Günter Zöchbauer
https://plnkr.co/edit/pt90F34KPsGoHDpSUQFD?p=preview,我需要从所选字符串加载小部件实例。 - Pratik Kelwalkar
2个回答

12

使用as来导入模块,例如

import * as widgets from './lib';
...
this.widgetInstance = new widgets[className](); 

Plunker示例

我记得这是从另一个回答中了解的,但我找不到它以便给予一些功劳 :-/


一如既往,你一直都很棒! - Pratik Kelwalkar

4
您可以使用`eval`函数根据类名创建一个对象:
class SomeClass
{
    x: number;
    y: number;
    constructor() {
        this.x = this.y = 1;
    }

}



function getWidgetObjectFromClassName(className : string) : {}
{
    return eval("new " + className + "();");
}

console.log("%o", getWidgetObjectFromClassName("SomeClass"));

Playground here


这个代码完全正常,但是在我的情况下,当我把SomeClass放在其他的ts文件中并且即使我导入它,它也找不到。请检查一下。 - Pratik Kelwalkar
2
可能需要包含模块或命名空间:getWidgetObjectFromClassName("ModuleOrNamespace.SomeClass") - Jesús López
这不是一个干净的解决方案,但绝对有效。为什么要踩呢? - titusfx
到目前为止,我找到的唯一解决方案,谢谢!不过可能是危险的。 - Raffael
@Raffael,你能解释一下为什么这很可能是危险的吗?是因为类名的歧义可能会导致返回错误的类吗? - hareluya86
由于函数可能会在类名的位置上注入一些JavaScript,因此存在危险性。通常情况下,字符串会被解析/编码以确保不会传递恶意执行的有效JavaScript。 - redevill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接