问题
I am working on solution in which i want to append dynamically created component after clicked row
I have table consist rows with action button on click of which i will call angular function and load component after that row.
Here is table code
<div class="row" *ngFor="let rData of reportData; let i = index;" >
<div class="col" >
<button class="btn btn-sm" (click)="loadChildComponent()">+</button>
</div>
<div class="col">Name</div>
<div class="col">Description</div>
<ng-template #dynamic></ng-template>
</div>
Code for dynamic components
Service.ts
import { DynamicComponent } from './dynamic.component'
@Injectable()
export class Service {
factoryResolver;
rootViewContainer;
constructor(@Inject(ComponentFactoryResolver) factoryResolver) {
this.factoryResolver = factoryResolver
}
setRootViewContainerRef(viewContainerRef) {
this.rootViewContainer = viewContainerRef
}
addDynamicComponent() {
const factory = this.factoryResolver
.resolveComponentFactory(DynamicComponent)
const component = factory
.create(this.rootViewContainer.parentInjector)
this.rootViewContainer.insert(component.hostView)
}
}
Here is component file.
dynamic.component.ts
import { Component } from '@angular/core'
@Component({
selector: 'dynamic-component',
template: `<div class="row" >
<div class="col">Data</div>
<div class="col">Data</div>
<div class="col">Data</div>
<div class="col">Data</div>
<div class="col">Data</div>
<div class="col">Data</div>
<div class="col">Data</div>
<ng-template #dynamic></ng-template>
</div>`
})
export class DynamicComponent { }
Functions used to render dynamic component
@ViewChild('dynamic', {
read: ViewContainerRef
}) viewContainerRef: ViewContainerRef
loadChildComponent() {
this.service.setRootViewContainerRef(this.viewContainerRef)
this.service.addDynamicComponent()
}
Right now its appending in same div for any of rows
i would like to append it after clicked row
Please help..
回答1:
The ng-template
in Angular acts like a ghost element i.e. it is never displayed directly. Check this link.
Update:
You are having the template inserted with first row always because you have used @ViewChild. @ViewChild looks for the first element in the template.
Try using @ViewChildren instead.
Refer the following changes:
<ng-container *ngFor="let rData of reportData; let i = index;">
<div class="row">
<div class="col" >
<button class="btn btn-sm" (click)="loadChildComponent(i)">+</button>
</div>
<div class="col">Name</div>
<div class="col">Description</div>
</div>
<div class="row">
<ng-template #dynamic></ng-template>
</div>
</ng-container>
JS changes:
@ViewChildren('dynamic', { read: ViewContainerRef }) viewContainerRef: QueryList<ViewContainerRef>
loadChildComponent(index) {
this.service.setRootViewContainerRef(this.viewContainerRef.toArray()[index])
this.service.addDynamicComponent()
}
Hope this helps :)
来源:https://stackoverflow.com/questions/52535851/insert-dynamically-create-component-after-clicked-row