且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-06-01 02:30:51

自动更新

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

Automatic update

This doesn't seem to be possible. Here is the explanation why.

对于每个组件,Angular编译器都会创建一个工厂.您可以在ng://文件夹

For each component, Angular compiler creates a factory. You can observe all factories in the sources tab under ng:// folder, here is the example of how it looks. When it creates a factory, it defines nodes that will be rendered inside this component view. Some of the nodes are child components.

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

And it is at the time of generating this factory it is defined which input properties the framework should track. So unless you defined input properties before the compilation, Angular will not be tracking and updating the inputs.

以下是该工厂的外观示例:

Here is an example of how this factory looks like:

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时,它实际上会搜索该工厂.它不会编译任何东西.

When you use this.componentFactoryResolver.resolveComponentFactory, it actually searches for that factory. It doesn't compile anything.

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

This certainly possible. You can query a child component from the parent component and update the property - it will be correctly rendered in the child component's template. And you can even trigger onChanges lifecycle hook.

export class AppComponent {
  @ViewChild(BComponent) bc;

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