gpt4 book ai didi

javascript - Typescript 和 Angular 2 反射

转载 作者:行者123 更新时间:2023-11-27 23:05:31 26 4
gpt4 key购买 nike

虽然这个主题已经在其他帖子中讨论过,如下所示:

Dynamically loading a typescript class (reflection for typescript)

我无法找到我的具体问题的答案。所以,如果这是重复的,请原谅我。

我正在尝试在 Angular 2 中创建一个非常简单的指令(使用 Typescript),它允许动态添加或删除由类型表示的一组控件。例如,如果类型是:

class Stone{
constructor(
public nameOfStone?: string,
public typeOfStone?: string
){}
}

用户界面将是这样的:

Screenshot 1

我可以在特定类型(例如:石头)上使用它。但是,鉴于该指令的目标只是添加此动态添加/删除功能,我认为参数化要创建的类型并将其用于不同的类型定义是有意义的。我在 Component 类中尝试了类似的方法:

import {Component} from 'angular2/core';
import {NgForm} from 'angular2/common';
import {ControlGroup, Control, FormBuilder, FORM_DIRECTIVES} from 'angular2/common'
@Component({
selector: 'stone-details',
templateUrl: '../stones/stone-details.component.html',
directives: [FORM_DIRECTIVES]
})
export class StoneComponent {
type = 'Stone';
Stones = new Array<Stone>();

addBtnClicked(){
let Stone = Object.create(window['Stone'].prototype);
//let Stone = new Stone('', '');
this.Stones.push(Stone);
}
removeBtnClicked(index: number){
if(index >= this.Stones.length){
alert('Not a valid index');
}else if(confirm('Remove this Stone?')){
this.Stones.splice(index, 1);
}
}
}

class Stone{
constructor(
public nameOfDeity?: string,
public typeOfDeity?: string
){}
}

当我使用注释行时let Stone = new Stone('', '');该组件工作完美,但如果我使用let Stone = Object.create(window['Stone'].prototype);它似乎不起作用,我看到的错误是angular2.dev.js:23941 原始异常:TypeError:无法读取未定义的属性“prototype”

我最初认为导出 Stone 类会有所帮助,但是所有疯狂的变体(导出类,尝试将该类引用为 window['StoneComponent'].export_1['Stone'])都没有帮助。我知道该组件在窗口组件下不直接可见,但我不确定我缺少什么。有其他方法可以做到这一点吗?我错过了什么吗?请指教。

P.S:我正在使用最新版本的 Angular 2 和 Typescript(几天前我启动了这个应用程序)。

最佳答案

您的代码的问题是定义顺序。

具体来说,类定义不像函数定义那样被提升。棘手的部分是,类型 Stone 被提升,这是完全有效的,但是 Stone,构造函数,不是。

要解决此问题,只需将 Stone 的定义移至组件上方,或将其提取到单独的模块中并导入即可。

不要尝试将其插入全局变量,例如window。这是一种非常糟糕的做法,并且会比人们想象的更快地导致错误和名称冲突。它还破坏了模块的优点。

简而言之,您需要的是

class Stone {
constructor(
readonly nameOfDeity?: string,
readonly typeOfDeity?: string
) {}
}

export class StoneComponent {
kind = 'Stone';
stones: Stone[] = [];

addBtnClicked() {
const stone = new Stone();
this.stones.push(stone);
}
removeBtnClicked(index: number) {
if (index >= this.stones.length) {
alert('Not a valid index');
} else if (confirm('Remove this Stone?')){
this.stones.splice(index, 1);
}
}
}

更新因为在最初的问题中,您声明这将是一个通用组件,并且您将拥有多个类,其中实际类由组件类的 kind 属性选择。您可能更想考虑以下模式。

组件字段种类.ts

export class Stone { ... }

export class Widget { ... }

export class Gizmo { ... }

通用组件.ts

import * as kinds from './component-field-kinds';

type Kind = keyof typeof kinds;

export class GenericComponent {
@Input() kind: Kind;

values: typeof kinds[Kind][] = [];

addBtnClicked() {
const value = new kinds[this.kind]();
this.values.push(value);
}

请注意,就其值(value)而言,JavaScript 和 TypeScript 都没有动态类加载器之类的东西。这就是该语言一直以来的工作方式,整个结构是一流的。

这不是 Java。

关于javascript - Typescript 和 Angular 2 反射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36637124/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com