如何从 Angular 中的类名中找到组件类的原型并获取该类原型中定义的属性值?
Posted
技术标签:
【中文标题】如何从 Angular 中的类名中找到组件类的原型并获取该类原型中定义的属性值?【英文标题】:How can I find the prototype of component class from class name in Angular and get the value of property defined in that class prototype? 【发布时间】:2018-04-26 04:37:38 【问题描述】:export class AppSample1Component
public propertyWithDefaultValue = 'Lorem ipsum dolor sit amet!';
是否可以在 Angular 中访问组件的类原型?
例如(这个不返回值):
console.log(AppSample1Component.prototype.propertyWithDefaultValue);
如果可能,我如何在路由解析器函数中获取类的原型?
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
const componentType = typeof route.component === 'string' ? route.component : route.component.name;
console.log('Class name of the component: ', componentType);
console.log('>>> I want to find the prototype of component class from ActivatedRouteSnapshot and get the value of "propertyWithDefaultValue" property of that class prototype in this section.');
return new Promise((resolve, reject) =>
Promise.all([
this.getData()
]).then(
() =>
// Init component(s) after prefetch data, etc...
resolve();
,
reject
);
);
您可以查看StackBlitz reproduction of the problem here。
编辑
我提到 Angular 是因为我想了解 Angular 是否有一个内部方法/属性来查找类属性元数据的映射,这允许我在路由器解析器方法中访问类的静态属性。 Angular 知道 route.component.name。所以我认为它可能有一个内部位置可以找到这种元数据。
// Here's an example which shows a minimal use of OOP in my recent javascript projects
const myLib =
apply: function (obj, config)
if (obj && config && typeof config === 'object')
for (var p in config)
obj[p] = config[p];
return obj;
,
extend: function (sc, bc)
var Fn = function () ;
Fn.prototype = bc.prototype;
var scpb = sc.prototype;
var scp = sc.prototype = new Fn();
scp.constructor = sc;
if (bc.prototype.constructor === Object.prototype.constructor)
bc.prototype.constructor = bc;
myLib.apply(scp, scpb);
sc.superclass = bc.prototype;
;
myLib.textField = function (config)
;
myLib.textField.prototype =
type: 'text'
;
myLib.numberField = function (config)
myLib.numberField.superclass.constructor.call(this, config);
;
myLib.numberField.prototype =
type: 'number',
min: 0,
max: 9999
;
myLib.extend(myLib.numberField, myLib.textField);
const obj1 = new myLib.textField();
const obj2 = new myLib.numberField();
console.group('My old JS way');
console.log(obj1.type, obj2.type);
console.log(myLib.textField.prototype.max, myLib.numberField.prototype.max);
console.groupEnd();
// And here is a demonstration of typescript generated javascript.
// Compiled typescript code generates javascript class as something like below.
// Typescript places the properties to the beginning of the constructor, not to prototype.
// This is why it's not possible to access class prototype directly.
myLib.numberField2 = function ()
this.type = 'number';
this.min = 0;
this.max = 9999;
//constructor block begin
//constructor block end
;
const obj3 = new myLib.numberField2();
console.group('Typescript compiled output demonstration');
console.log(obj3.max); // prints 9999
console.log(myLib.numberField2.prototype.max);
// this prints "undefined" because max property doesn't exist before object creation
console.groupEnd();
【问题讨论】:
你认为为什么会变成AppSample1Component.prototype.propertyWithDefaultValue
? typescriptlang.org/play/…
为什么还要设置内置类的原型?扩展它并在自定义子类中设置您的自定义变量。
@yurzui 该语法是我用来访问 javascript 中的类原型属性的语法。这就是为什么我写它来作为一个例子。不是因为我认为它应该变成那种形式。
@omeralper 是的,你是对的。这只是为了演示问题。我正在尝试了解是否可以访问该属性,而我只是将组件的类名放在字符串变量中。
【参考方案1】:
如果我理解您的问题,您是在问“是否可以动态解析给定名称的类?”
您尝试调用此代码的位置以及您是否使用 Angular 似乎与问题无关。
这个问题的一般答案是“不”。类/模块在您的应用程序中不一定具有唯一的名称。例如,您可以在导入它们时重命名它们(例如import LongClassName as LCN from "./long-class-name";
)。并且可以有多个同名的类。
假设您已经导入了所有可能需要解析的类,或者正在当前模块中定义它们,您可以使用eval(classNameToResolve).prototype
来获取类原型。但是,出于安全和性能原因,强烈建议不要使用 eval
。而且它不适用于所有模块捆绑器,或者如果您缩小代码。
所以,简而言之,不。考虑创建一个允许您进行所需查找的映射,例如
const ALL_MY_CLASSES =
ClassA: ClassA,
ClassB: ClassB
然后您将能够使用ALL_MY_CLASSES[classNameToResolve].prototype
进行查找。当然,您确实需要添加您可能遇到的所有类。
【讨论】:
感谢您的回答。我已经为问题的增强版准备了jsfiddle.net/hallilibrahim/wvm17c8d。以上是关于如何从 Angular 中的类名中找到组件类的原型并获取该类原型中定义的属性值?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Angular 2 中的数据渲染静态 Angular 组件? [复制]