我有以下html(为了说明而简化)。
//removed irrelevant HTML
<tbody>
<tr *ngFor="let el of elements; let i = index" >
<td>
<button (click)="showTemplate(i, $event)">Click me {{i}}</button>
</td>
</tr>
</tbody>
<template #myTemplate>
<tr>
<td>You have clicked a button</td>
</tr>
</template>
我想要实现的是,当在特定tr
中单击按钮时,应在特定tr
之后插入模板。
我认为我能做的是使用ViewChild
获取templateRef,然后获取其节点并使用类似的内容:
@ViewChild('myTemplate', {read: TemplateRef}) myTemplate;
showTemplate(i, event) {
// i would get selectedTR from the event
selectedTR.insertAdjacentElement('afterend', this.myTemplate.elementRef.nativeElement)`
}
但是我在运行该函数时从this.myTemplate.elementRef.nativeElement
获得的是
我遵循的方法是正确的吗?如果是,那么我的设置可能出错?如果没有,是否有更多面向角度的解决方案?
请注意我正在使用Angular 2。
答案 0 :(得分:3)
虽然它没有回答关于插入模板的问题,但以下是我将如何解决您的问题:
<tbody>
<ng-container *ngFor="let el of elements; let i = index">
<tr>
<td>
<button (click)="showTemplate(el)">Click me {{i}}</button>
</td>
</tr>
<tr *ngIf="el.showTemplate">
<td>You have clicked a button</td>
</tr>
</ng-container>
</tbody>
TS:
showTemplate(el: any): void {
el.showTemplate = true;
}
这实际上是与模板绑定相同的解决方案,虽然它更简单,模板HTML(在这种情况下是第二个TR)正确绑定到模型。
答案 1 :(得分:0)
如果您不想使用*ngIf
并且对模板内容保持灵活性,那么动态加载组件是另一种方式。
<强> app.component.ts 强>
import { Component, Input, OnInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<tbody>
<tr *ngFor="let el of elements; let i = index" >
<td>
<row-container [element]="el"></row-container>
</td>
</tr>
</tbody>
`
})
export class AppComponent {
elements = [
{id: 1, name: "Element 1", content: "This is element 1 content"},
{id: 2, name: "Element 2", content: "This is element 2 content"},
{id: 3, name: "Element 3", content: "This is element 3 content"},
];
constructor() { }
}
<强>行container.component.ts 强>
import {
Component,
ViewContainerRef,
Input,
ViewChild,
Compiler,
NgModule,
Injector,
NgModuleRef
} from '@angular/core';
export class Element {
constructor(
public id: number,
public name: string,
public content: string){}
}
@Component({
selector: 'row-container',
template: `
<button (click)="onRowClick()">{{element.name}} </button>
<ng-container #vc><ng-container>
`
})
export class RowContainerComponent {
@Input() element: Element;
@ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
constructor(
private compiler: Compiler,
private injector: Injector,
private moduleRef: NgModuleRef<any>){
}
onRowClick(){
this.loadComponent();
}
loadComponent(){
this.vc.detach();
const template = "<div><span>{{name}}</span></div>";
const tmpComp = Component({template: template})(class{});
const tmpModule = NgModule({declarations: [tmpComp]})(class{});
// Compile module and all components
this.compiler.compileModuleAndAllComponentsAsync(tmpModule)
.then((factories) =>{
const f = factories.componentFactories[0];
const compRef = f.create(this.injector, [], null, this.moduleRef);
compRef.instance.name = this.element.content;
this.vc.insert(compRef.hostView);
});
}
}