typescript 将数据传递到动态生成的组件的@Input()在stackblitz中可以工作,但在我自己的计算机上不行

5ssjco0h  于 2023-05-30  发布在  TypeScript
关注(0)|答案(2)|浏览(204)

我在Angular 13中使用ViewContainerRef.createComponent()动态创建一个组件,如下所示

const componentInstance : ComponentRef<unknown> = this.vcRef.createComponent(YourComponent);

在某些情况下,我想在将数据嵌入视图之前将其传递到组件中,起初我不知道如何做到这一点,但当制作this stackblitz来突出问题时,我最终通过这样做来解决问题

componentInstance.instance['PropName'] = 'some value';

但是在我的电脑上它无法编译,因为我得到一个Object is of type unknown错误。有人能解释一下为什么会这样吗?

nhhxz33t

nhhxz33t1#

这是因为您将YourComponent类型分配给unknown类型,如下所示:

const componentInstance : ComponentRef<unknown> = this.vcRef.createComponent(YourComponent);

然后尝试访问属性:

componentInstance.instance['PropName'] = 'some value';

方案一

要解决这个问题,首先需要在使用unknown类型之前输入guard:

if(componentInstance instanceof YourComponent)
  componentInstance.instance['PropName'] = 'some value';

这基本上就是unknown的用途。当我们事先不知道类型时使用它。然后我们有一堆type guard,在我们调用它的函数/属性之前,将它引导到正确的类型。
示例:

function print(x: unknown) {

  if(typeof x === 'string')
    return 'x is string';
  
  if(x instanceof YourComponent)
    return x.name;
}

方案二

另一种解决方案是在赋值过程中给予实际的类型:

const componentInstance : ComponentRef<YourComponent> = this.vcRef.createComponent(YourComponent);

方案三

或者根本不给出任何显式类型,因为TypeScript可以从赋值的左手推断类型:

const componentInstance = this.vcRef.createComponent(YourComponent);
7gyucuyw

7gyucuyw2#

v14.1.0开始,Angular在组件引用中添加了setInput()方法:
分享来自this article的优雅解决方案:

@Directive({
  selector: '[container]',
})
export class ContainerDirective {
  constructor(private vcr: ViewContainerRef) {}

  ngOnInit() {
    const ref = this.vcr.createComponent(FooComponent);
    ref.setInput('text', 'Angular');
    ref.setInput('myAlias', 'v14.1.0');
    // This will throw an error
    ref.setInput('doesNotExist', 'error');
  }
}

相关问题