简体   繁体   English

如何在Typescript / Angular2中返回动态类型的对象?

[英]How can you return a dynamically typed object in Typescript / Angular2?

I am trying to create a modal generator service. 我正在尝试创建模式生成器服务。 Ultimately, I would like to use it to creative various types of modals. 最终,我想用它来创建各种类型的模态。

I have a function to create modal components, and I would like it to accept various types of modal components as input, and return a ComponentRef< (modaltype) > as output. 我有一个创建模态组件的函数,我希望它接受各种类型的模态组件作为输入,并返回ComponentRef <(modaltype)>作为输出。 The problem is that I am having some trouble with the syntax. 问题是我在语法上遇到了麻烦。

The problem, specifically, is the function declaration. 问题特别是函数声明。 This is what it looks like right now: 这是现在的样子:

private createModalComponent (compType : Type<Component>, vCref: ViewContainerRef): ComponentRef<compType> { ... }

This is giving me the error that "cannot find name 'compType'", which makes sense. 这给了我一个错误,“找不到名称'compType'”,这是有道理的。 So I also tried a more generic approach: 所以我也尝试了一种更通用的方法:

private createModalComponent<T> (compType : T, vCref: ViewContainerRef): ComponentRef<T> { ... }

But that gave me the error that "Argument of type 'T' is not assignable to parameter of type 'Type<{}>'. 但这给了我一个错误:“类型'T'的参数不能分配给类型'Type <{}>的参数。

So I'm stumped. 所以我很困惑。 How does one go about returning a dynamically typed object in typescript? 如何在打字稿中返回动态键入的对象?

import { Injectable, ViewChild, ViewContainerRef, ElementRef,
         EventEmitter, OnInit, ComponentRef, ComponentFactoryResolver,
         Type, ReflectiveInjector } from '@angular/core';
import { WizardModalComponent } from './wizard-modal/wizard-modal.component'


@Injectable()
export class ModalGeneratorService {

  constructor(private _cmpFctryRslvr: ComponentFactoryResolver, private _vcRef: ViewContainerRef) {}

  private createModalComponent (compType : Type<Component>, vCref: ViewContainerRef): ComponentRef<compType> {
    let factory = this._cmpFctryRslvr.resolveComponentFactory(compType);
    // vCref is needed cause of that injector..
    let injector = ReflectiveInjector.fromResolvedProviders([], vCref.parentInjector);
    // create component without adding it directly to the DOM
    let comp = factory.create(injector);
    return comp;
  }

  createWizardModalcomponent(vCref : ViewContainerRef) {
    createModalComponent(WizardModalComponent, vCref);
  }
}

This might be the answer so posting it here: 这可能是答案,因此请在此处发布:

I looked in the file ComponentFactory from the angular 2 framework itself; 我从angular 2框架本身查看了ComponentFactory文件。 it uses "any", but further in, here is how it declares the create function (note the "<C>"): 它使用“ any”,但更进一步地,它是如何声明create函数的(请注意“ <C>”):

create(injector: Injector, projectableNodes?: any[][], rootSelectorOrNode?: string|any) : ComponentRef<C>

https://angular.io/docs/ts/latest/api/core/index/ComponentFactory-class.html https://angular.io/docs/ts/latest/api/core/index/ComponentFactory-class.html

Not exactly sure I understand the problem fully, but this might work: 不确定我是否完全理解问题,但这可能有用:

private createModalComponent<T extends Type<{}>> (compType : T, vCref: ViewContainerRef): ComponentRef<T> { ... }

So you're declaring a generic type but restraining it to either be or extend the Type<{}> type, which is what the second error you had was saying. 所以,你声明一个泛型类型,但它抑制要么或扩展Type<{}>类型,这就是你有第二个错误是说。

Thank you everyone who commented or answered, I found an answer that works exactly the way I want and it is very simple. 谢谢所有发表评论或回答的人,我找到了一个完全按照我想要的方式工作的答案,它非常简单。

I simply use the 'any' type in place of the component type for component ref, like so: 我只是使用'any'类型代替了组件类型的组件ref,就像这样:

private createModalComponent (compType : Type<Component>, vCref: ViewContainerRef): ComponentRef<any> { ... }

At times like these, it always helps to remember that, although Typescript generally uses static typing, it is merciful enough to grant us the 'any' keyword. 在此类情况下,尽管Typescript通常使用静态类型输入,但总是有助记住这一点,它足以使我们获得'any'关键字。 Hope someone else finds this useful. 希望其他人觉得这有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM