是否可以在运行时动态设置组件@Input?

丹尼尔·库克(Daniel Cooke)

说我有一个dynamic-component-wrapper可以实例化Component传递给它的任何类的实例

// DRE013 DCOOKE 16/05/2017 - The component to instantiate.
@Input() componentType: Type<{}>;

// DRE013 DCOOKE 16/05/2017 - the component that will be created
private _cmpRef: ComponentRef<Component>;


// DRE013 DCOOKE 16/05/2017 - Creates a component ref in the view at #target
createComponent(){

    let factory = this.componentFactoryResolver.resolveComponentFactory(this.componentType);
    this._cmpRef = this.target.createComponent(factory);
    //this._cmpRef.instance.inputs >>>>>>>>> this is a string[] and I do not see how I can use this 
}

用法示例

<shared-dynamic-component [componentType]="TestComponent"></shared-dynamic-component>

哪里 TestComponent = TestComponent //class

这可以按预期工作,并且我可以从dynamic-component-wrapper类似的内部接收到此组件的实例,如下所示:

this._cmpRef.instance

对此对象Angular文档尚不清楚instance-只是说明实例的类型C-绝对没有引用C的实际含义。

幸运的是,我的IDE能够告诉我:

ComponentRef.instance 具有以下属性:

  • inputs : string[]
  • outputs : string[]

但是,我不明白如何使用此信息。我想像这仅仅是名称的的@Input领域-但我不认为我怎么能在一个复杂的对象作为输入传递。

在使用动态创建组件之后,我是否可以设置@Inputs和其他元数据componentFactoryResolver

马克斯·科雷茨基(Max Koretskyi)

自动更新

这似乎不可能。这是为什么的解释。

Angular编译器为每个组件创建一个工厂。您可以sourcesng://文件夹选项卡中观察所有工厂这是外观的示例创建工厂时,它定义nodes了将在此组件视图内呈现的工厂一些节点是子组件。

正是在生成该工厂时,定义了框架应跟踪的输入属性。因此,除非您在编译之前定义了输入属性,否则Angular将不会跟踪和更新输入。

这是该工厂外观的示例:

function View_AppComponent_0(l) {
  return jit_viewDef2(0,[
    jit_queryDef3(201326592,1,{someComp: 0}),
    (l()(),jit_elementDef4(0,null,null,1,'h1',[],null,null,null,null,null)),
    (l()(),jit_textDef5(null,[
      'Hello ',
      ''
    ]
    )),
    (l()(),jit_textDef5(null,['\n\n'])),
    (l()(),jit_elementDef4(0,null,null,1,'b-comp',[],null,null,null,jit_View_BComponent_06,jit__object_Object_7)),

      *************************************
      // this is a child component's node definition which has `some` property binding
      jit_directiveDef8(24576,null,0,jit_BComponent9,[],{some: [
        0,
        'some'  <------------------------ property name to track
      ]
    },null)
     **************************************************

  ]

当您使用时this.componentFactoryResolver.resolveComponentFactory,它实际上会搜索该工厂。它不会编译任何东西。

手动更新

当然可以。您可以从父组件中查询子组件并更新属性-它会在子组件的模板中正确呈现。您甚至可以触发onChanges生命周期挂钩。

export class AppComponent {
  @ViewChild(BComponent) bc;

  ngAfterViewInit() {
    setTimeout(() => {
      this.bc.some = 'foo';
      const changes = {some: new SimpleChange('', 'foo', true)};
      this.bc.ngOnChanges(changes);
    })
  }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章