[英]Dynamic Tabs with dynamic content using ComponentResolver in Angular 2
受到Angular 2动态选项卡的启发,用户单击选择的组件并在使用ComponentResolver动态创建Angular 2组件时传递输入我正在尝试进一步,不仅这些选项卡获得了动态组件,而且be选项卡的内容由动态组件组成。 在原始示例中,我将组件C1-C3用于选项卡,并希望对部分使用C4和C5。 我知道实际的制表符没有任何样式/功能,但是结构应该足以让我前进。 我做的。
//our root app component
import {Component, ComponentRef, Input, ViewContainerRef, ComponentResolver, ViewChild, Injectable, OnInit} from '@angular/core';
@Component({
selector: 'dcl-wrapper',
template: `<div #target></div>`
})
export class DclWrapper {
@ViewChild('target', {read: ViewContainerRef}) target;
@Input() type;
cmpRef:ComponentRef;
private isViewInitialized:boolean = false;
constructor(private resolver: ComponentResolver) {}
updateComponent() {
if(!this.isViewInitialized) {
return;
}
if(this.cmpRef) {
this.cmpRef.destroy();
}
this.resolver.resolveComponent(this.type.type).then((factory:ComponentFactory<any>) => {
this.cmpRef = this.target.createComponent(factory);
this.cmpRef.instance.info = this.type;
});
}
ngOnChanges() {
this.updateComponent();
}
ngAfterViewInit() {
this.isViewInitialized = true;
this.updateComponent();
}
ngOnDestroy() {
if(this.cmpRef) {
this.cmpRef.destroy();
}
}
}
@Component({
selector: 'child-dcl-wrapper',
template: `<div #target></div>`
})
export class ChildDclWrapper {
@ViewChild('target', {read: ViewContainerRef}) target;
@Input() type;
cmpRef:ComponentRef;
private isViewInitialized:boolean = false;
constructor(private resolver: ComponentResolver) {}
updateComponent() {
if(!this.isViewInitialized) {
return;
}
if(this.cmpRef) {
this.cmpRef.destroy();
}
this.resolver.resolveComponent(this.type.type).then((factory:ComponentFactory<any>) => {
this.cmpRef = this.target.createComponent(factory);
this.cmpRef.instance.info = this.type;
});
}
ngOnChanges() {
this.updateComponent();
}
ngAfterViewInit() {
this.isViewInitialized = true;
this.updateComponent();
}
ngOnDestroy() {
if(this.cmpRef) {
this.cmpRef.destroy();
}
}
}
@Component({
selector: 'c1',
template: `<h2>c1</h2><p>{{info.name}}</p>
<my-sections [sections]="section"></my-sections>`
})
export class C1 {
}
@Component({
selector: 'c2',
template: `<h2>c2</h2><p>{{info.name}}</p>
<my-sections [sections]="section"></my-sections>`
})
export class C2 {
}
@Component({
selector: 'c3',
template: `<h2>c3</h2><p>{{info.name}}</p>
<my-sections [sections]="section"></my-sections>`
})
export class C3 {
}
@Component({
selector: 'c4',
template: `<h2>c4</h2><p>{{info.name}}</p>`
})
export class C4 {
}
@Component({
selector: 'c5',
template: `<h2>c5</h2><p>{{info.name}}</p>`
})
export class C5 {
}
@Component({
selector: 'my-sections',
directives: [ChildDclWrapper],
template: `
<h3>Sections</h3>
<div *ngFor="let section of type.sections">
<child-dcl-wrapper [type]="section"></child-dcl-wrapper>
</div>
`
})
export class Sections {
@Input() sections;
}
@Component({
selector: 'my-tabs',
directives: [DclWrapper],
template: `
<h2>Tabs</h2>
<div *ngFor="let tab of tabs">
<dcl-wrapper [type]="tab"></dcl-wrapper>
</div>
`
})
export class Tabs {
@Input() tabs;
}
@Injectable()
export class AService {
info = [
{
name: "taco",
type: C1,
sections: [
{
name: "believe",
type: C4
},
{
name: "car",
type: C5
}
]
},
{
name: "pete",
type: C2,
sections: [
{
name: "repeat",
type: C4
},
{
name: "banana",
type: C5
}
]
},
{
name: "carl",
type: C3,
sections: [
{
name: "shotgun",
type: C4
},
{
name: "helmet",
type: C5
}
]
}
];
getServiceInfo() {
console.log("Bung.");
return this.info;
}
}
@Component({
selector: 'my-app',
directives: [Tabs],
providers: [AService],
template: `
<h1>Hello {{name}}</h1>
<my-tabs [tabs]="types"></my-tabs>
`
})
export class App extends OnInit {
types;
aService;
constructor(private aService: AService) {
this.aService = aService;
}
getInfo() {
console.log("beep");
this.types = this.aService.getServiceInfo();
}
ngOnInit() {
console.log("boop");
this.getInfo();
}
}
我在您的代码中看到了几个错误。 例如,您需要使用info.sections
而不是下面的代码中的section
:
<my-sections [sections]="section"></my-sections>
它应该是:
<my-sections [sections]="info.sections"></my-sections>
您也忘记添加像这样的Sections
指令:
@Component({
selector: 'c1',
template: `<h2>c1</h2><p>{{info.name}}</p>
<my-sections [sections]="info.sections"></my-sections>`,
directives: [Sections] <== add this line
})
export class C1 {}
而且,您可以使用一个DclWrapper
来做到这一点。
更新的plunkr在这里https://plnkr.co/edit/JRyqou9yC6LvSRrCR3eA?p=preview
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.