如何将@Input用于使用ComponentFactoryResolver创建的组件?

bad*_*013 48 angular

是否有一种方法可用于在动态创建的Angular 2组件上定义@Input属性?

我正在使用ComponentFactoryResolver在容器组件中创建组件.例如:

let componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentName);

let componentRef = entryPoint.createComponent(componentFactory);
Run Code Online (Sandbox Code Playgroud)

其中"entryPoint"在组件HTML中是这样的:

<div #entryPoint></div>
Run Code Online (Sandbox Code Playgroud)

并在我的容器组件中定义:

@ViewChild('entryPoint', { read: ViewContainerRef } entryPoint: ViewContainerRef;
Run Code Online (Sandbox Code Playgroud)

这很好用,但我找不到让@Input属性在新创建的组件上工作的方法.我知道您可以在组件类上显式设置公共属性,但这似乎不适用于ng-reflect.在进行此更改之前,我有一个"选定"属性,用"@Input()"装饰,导致Angular将以下内容添加到DOM:

<my-component ng-reflected-selected="true"></my-component>
Run Code Online (Sandbox Code Playgroud)

有了这个,我就能够动态更新标记来切换CSS类:

<div class="header" [class.active-header]="selected === true"></div>
Run Code Online (Sandbox Code Playgroud)

根据一些搜索,我能够找到一种方法使"@Output"按预期工作,但我还没有为@Input找到任何东西.

让我知道是否有其他背景会有所帮助,我很乐意添加它.

Gün*_*uer 53

不,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 = data);
Run Code Online (Sandbox Code Playgroud)

  • 当我这样做时, componentRef.instance.someProp = 'someValue'; 不会在子组件上触发 ngOnChanges。这项拖车工作还需要完成更多步骤吗? (3认同)

hov*_*ado 22

14.1.0开始,Angular 添加了setInput()方法来直接设置或更新 @Input 到组件引用。

this.componentRef.setInput('someInput', this.value);
Run Code Online (Sandbox Code Playgroud)

使用此方法将使用 OnPush 更改检测策略正确标记检查组件。它还将确保在检测到动态创建的组件发生更改时运行 OnChanges 生命周期挂钩。

如果值会改变,我使用这种方法:

@Input()
public value: string;    

ngOnInit(): void {
    this.viewContainerRef.clear();
    this.componentRef = this.viewContainerRef.createComponent(this.component);
}

ngOnChanges(changes: SimpleChanges): void {
    if (changes.value) {
        this.componentRef?.setInput('someInput', this.value); // Updated with every change from the parent component.
    }
}

ngOnDestroy(): void {
    this.componentRef?.destroy(); // Don't forget to destroy the component.
}
Run Code Online (Sandbox Code Playgroud)

应用程序编程接口

  • 这是 &gt;14 的正确答案 (2认同)
  • 完整文章:https://netbasal.com/a-new-way-to-set-inputs-on-angular-componentrefs-6214f95db63d (2认同)