【问题标题】:Is there a way to access @Input variables in a dynamically created component?有没有办法在动态创建的组件中访问 @Input 变量?
【发布时间】:2023-03-30 16:45:02
【问题描述】:

我正在向表单动态添加行,并希望每个新行都有一个唯一的 ID 号。

我有以下代码来添加一个新组件(代表一个新行),但我发现component.instance 只包含新创建的组件的“正常”属性,而不是用@Input() 修饰的属性。有没有办法动态写入/修改@Input() 属性?当一个人动态地创建一个组件时,人们自然会认为必须有一种直接的方法来以某种方式提供@Input() 值!

const componentFactory = this.componentFactoryResolver.resolveComponentFactory(thisType);
const component = this.subEnrollForm.container.createComponent(componentFactory);
component.instance.rowData.push(newRow); //rowData is a property in the
                                       dynamically-created component and 
                                       is decorated with @Input()

这是动态创建的组件:

export class SubEnrollFormRowComponent implements OnInit, DoCheck, OnChanges, AfterContentInit, AfterViewInit {
 @Input() rowData; 
  objKeys: Array<any> = [];
  subKeys: Array<any> = [];

我看到一个旧帖子有以下答案,但我希望随后添加了新功能来解决这个问题:

不,Angular2 绑定仅适用于组件和指令 静态添加到组件的模板中。

对于所有其他情况,请使用如中所述的共享服务 https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service

你也可以使用

let componentRef = entryPoint.createComponent(componentFactory); componentRef.instance.someProp = 'someValue'; componentRef.instance.someObservableOrEventEmitter.subscribe(data => this.prop = 数据);

后一种解决方案对我不起作用,另一个将组件转换为类型&lt;any&gt; 的建议也没有。我对上面提到的services 方法的解释是,我需要创建一个 Observable 供孙子订阅,以监视祖父母何时尝试更新孙子的 @Input() 属性,但这种方法在我看来是大量的矫枉过正,大量不必要的编码和开销来实现应该非常简单和直接的事情(除非我错过了一些东西,这很可能!)。如果有人有一种相对简单的方法来初始化/动态修改用@Input 装饰的孙组件属性,请提前非常感谢!

【问题讨论】:

  • 一种解决方案可能是添加一个未使用@Input 修饰的属性,然后使用该属性在后续的生命周期钩子中更新@Input 属性。 . .但同样,这似乎有点像黑客,我很想知道是否有更优雅/直接的方式来更新/写入 @Input 属性。 . .
  • 这一直是可能的。 Angular 文档中的工作示例:angular.io/generated/live-examples/dynamic-component-loader/…。组件hero-job-adhero-job-profile 是动态创建的,它们的@Input() data 属性在运行时设置。

标签: angular


【解决方案1】:

@Input 修饰的属性仍然是类属性,并且可以像任何其他属性一样访问。

我创建了一个工作示例: https://stackblitz.com/edit/angular-6-template-yih3sx?file=src%2Fapp%2Fapp.component.ts

【讨论】:

  • 非常好的例子。
  • 非常感谢,非常感谢!因此,除非我误读,否则看起来诀窍就在:(&lt;AdComponent&gt;componentRef.instance).data = adItem.data; 中,我们将带有 @Input 的组件转换为另一种类型,其中 data 属性没有用 @Input 装饰。 . .非常聪明!
  • 这不是必需的。 Angular 示例这样做是因为他们的示例稍微复杂一些。如果您查看我的示例,我将转换为DynamicComponent,它仍然具有@Input 装饰器,并且仍然有效。装饰器不会以任何方式影响/隐藏属性。
猜你喜欢
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
  • 2022-10-12
  • 1970-01-01
  • 2022-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多