2016-06-23 11 views
0

Inspiriert von Angular 2 dynamic tabs with user-click chosen components und Passing Input while creating Angular 2 Component dynamically using ComponentResolver Ich versuche, einen Schritt weiter zu gehen und nicht nur die Registerkarten eine dynamische Komponente zu bekommen, sondern auch den Inhalt der Registerkarte dynamische Komponenten enthalten. Aus dem ursprünglichen Beispiel habe ich die Komponenten C1-C3 für die Registerkarten verwendet und möchte C4 und C5 für Abschnitte verwenden. Ich bin mir bewusst, dass es kein Styling/Funktionalität für das eigentliche Tabbing gibt, aber die Struktur sollte ausreichen, um mich auf den Weg zu bringen. I made this.Dynamische Tabs mit dynamischem Inhalt mit ComponentResolver in Angular 2

//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(); 
    } 
} 
+0

Nun crud, rufen Sie mich einfach Herr Overcomplicater. – davimusprime

+0

@Yurzui, werfen Sie eine Antwort nach unten und ich werde es akzeptieren. – davimusprime

Antwort

2

Ich sehe mehrere Fehler im Code. Zum Beispiel müssen Sie info.sections stattdessen nur section im folgenden Code verwenden:

<my-sections [sections]="section"></my-sections> 

Es sollte:

<my-sections [sections]="info.sections"></my-sections> 

auch vergessen haben, Sections Richtlinie wie folgt hinzuzufügen:

@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 {} 

Und Sie können eine DclWrapper verwenden, um das zu tun.

Die aktualisierte plunkr hier ist https://plnkr.co/edit/JRyqou9yC6LvSRrCR3eA?p=preview

Verwandte Themen