我想做什么
我正在制作一个投票系统,它将在网站周围的多个组件中重复使用.为了保持干燥,我想从任何组件创建投票组件到指定的DOM元素.创建组件后,必须设置实例变量(在这种情况下模型:string和pk:number,都是公共的).
预期结果
我希望组件在指定位置呈现,打印在工厂创建组件后立即设置的正确数据.投票底部的输出应为Model:project PK:1
实际情况
ComponentFactory目前有两个由Component工厂创建的投票组件的输出:
>在正确的位置(目标div),但没有设置实例变量.
一些代码
@NgModule({ .. declarations: [ AppComponent,ProjectComponent,// parent for voteContainer VoteComponent,// Dynamic component ],entryComponents: [ VoteComponent,],.. })
包含VoteComponent工厂的父组件
export class ProjectDetailComponent implements AfterViewInit { @ViewChild('voteComponentContainer',{read: ViewContainerRef}) voteComponentContainer; public ngAfterViewInit() { this.factoryVoteComponent(); } private factoryVoteComponent() { const voteComponentFactory = this.componentFactoryResolver.resolveComponentFactory(VoteComponent); const voteComponentRef = this.viewContainerRef.createComponent(voteComponentFactory); voteComponentRef.instance.model = "project"; voteComponentRef.instance.pk = 1; voteComponentRef.changeDetectorRef.detectChanges(); } }
动态组件目标:
<vote-component-container></vote-component-container>
基本投票组件
@Component({ selector: 'vote-component-container',templateUrl: 'vote.component.html',}) export class VoteComponent { public model:string; public pk:number; public constructor(){} }
我试过了什么
我已经在这方面挣扎了很长一段时间,所以那里
是一些尝试让它工作.最后的尝试是
为工厂创建ViewChild.
我想问的是什么
对于我现在正在尝试的情况,有没有人对动态组件的使用有任何经验?我希望在正确的方向上推动如何解决在正确的位置呈现的组件的问题,但没有可用的属性.
解决方法
经过一些研究,测试失败并尝试了更多 – 我发现它是一个解决方案.我还不是100%满意,因为它变得有点干燥和有组织 – 但是现在:
首先,我必须调整将数据传递给动态生成的组件的方式.我不得不更新我的选择器目标以接受所需的属性.在我的案例模型和objectId.
<vote-component-container [model]="'project'" [objectId]="projectId"></vote-component-container>
要将此数据链接到VoteComponent,VoteComponent本身需要@Input setter用于这些数据输入,例如:
import { Input,Component,AfterViewInit } from '@angular/core'; @Component({ selector: 'vote-component-container',}) export class VoteComponent implements AfterViewInit { // Temp public for testing public _objectId:number; public _model:string; public constructor(){} public ngAfterViewInit(){ this.getVotes(); } @Input('objectId') set objectId(objectId:number){ this._objectId = objectId; } @Input('model') set model(model:string){ this._model = model; } public getVotes(){ ... } }
并且最终在我的父组件中,我期望params [‘id’]部分是在ngAfterInit中调用函数的时候.但它没有,所以我不得不等待承诺..
@ViewChild('voteComponentContainer',{read: ViewContainerRef}) target: ViewContainerRef; private factoryVoteComponent(){ this.activatedRoute.params.subscribe((params: Params) => { this.model = 'project'; this.projectId = params['id']; let voteComponentFactory = this.componentFactoryResolver.resolveComponentFactory(VoteComponent); this.voteComponentRef = this.viewContainerRef.createComponent(voteComponentFactory); this.voteComponentRef.changeDetectorRef.detectChanges(); }); }