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

Dan*_*oke 4 angular

假设我有一个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 
}
Run Code Online (Sandbox Code Playgroud)

用法示例

<shared-dynamic-component [componentType]="TestComponent"></shared-dynamic-component>
Run Code Online (Sandbox Code Playgroud)

哪里 TestComponent = TestComponent //class

这按预期工作,我可以从内部接收此组件的实例,dynamic-component-wrapper因此:

this._cmpRef.instance

角文档是不是这个明确的instance目标-简单地指出实例类型C-完全没有参考什么C实际上是.

谢天谢地,我的IDE能够告诉我:

ComponentRef.instance 具有以下属性:

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

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

在动态创建具有?的组件之后,我是否可以设置@Inputs其他元数据componentFactoryResolver

Max*_*kyi 5

自动更新

这似乎不可能.这是解释原因.

对于每个组件,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)
     **************************************************

  ]
Run Code Online (Sandbox Code Playgroud)

当您使用时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);
    })
  }
Run Code Online (Sandbox Code Playgroud)