2016-09-30 4 views
0

Я пытаюсь использовать динамический компонент, предоставленный @ GünterZöchbauer здесь Angular 2 dynamic tabs with user-click chosen components для создания строк и столбцов. Пока я успешно добавил строки, но все равно не могу получить столбцы, созданные внутри строк.Угловые2 динамически добавленные элементы

Вот мой код:

DesignerModule

import { NgModule }  from '@angular/core'; 
import { CommonModule } from '@angular/common'; 

import { MaterializeModule } from '../../shared/materialize/materialize.module'; 

import { DesignerComponent } from './designer.component'; 

import { RowComponent } from './designer.component'; 
import { ColumnComponent } from './designer.component'; 

import { DynWrapperComponent } from './dyn-wrapper.component'; 


@NgModule({ 
    imports: [ 
    CommonModule, 
    MaterializeModule, 
    ], 
    declarations: [ 
    DesignerComponent, 
    DynWrapperComponent, 
    RowComponent, 
    ColumnComponent, 
    ], 
    entryComponents: [ 
    RowComponent, 
    ColumnComponent, 
    ], 
    providers: [ 

    ] 
}) 

export class DesignerModule {} 

DynWrapperComponent

import { Component, Compiler, ViewContainerRef, ViewChild, Input, ElementRef, 
     ComponentRef, ComponentFactory, ComponentFactoryResolver} from '@angular/core' 
import {BrowserModule} from '@angular/platform-browser' 

// Helper component to add dynamic components 
@Component({ 
    moduleId: module.id, 
    selector: 'dcl-wrapper', 
    template: `<div #target></div>` 
}) 
export class DynWrapperComponent { 
    @ViewChild('target', {read: ViewContainerRef}) target: any; 
    @Input() type: any; 
    cmpRef:ComponentRef<any>; 
    private isViewInitialized:boolean = false; 

    constructor(private componentFactoryResolver: ComponentFactoryResolver, 
       private compiler: Compiler, 
       private el: ElementRef) {} 

    updateComponent() { 
    if(!this.isViewInitialized) { 
     return; 
    } 
    if(this.cmpRef) { 
     this.cmpRef.destroy(); 
    } 

    let factory = this.componentFactoryResolver.resolveComponentFactory(this.type); 

    //this.resolver.resolveComponent(this.type).then((factory:ComponentFactory<any>) => { 
    this.cmpRef = this.target.createComponent(factory) 
    } 

    ngOnChanges() { 
    this.updateComponent(); 
    } 

    ngAfterViewInit() { 
    this.isViewInitialized = true; 
    this.updateComponent();  
    } 

    ngOnDestroy() { 
    if(this.cmpRef) { 
     this.cmpRef.destroy(); 
    } 
    } 
} 

DesignerComponent

import { Component, ViewChild, ElementRef, ContentChildren } from '@angular/core'; 


@Component({ 
    moduleId: module.id, 
    selector: 'my-row', 
    templateUrl: 'row.component.html', 
    styles: [ 
    `.row:hover { 
     border: 3px dashed #880e4f ; 
     } 
    ` 
    ] 
}) 

export class RowComponent { 

    colIndex: number = 0; 
    colList: Object[] = []; 

    addColumn() { 
    this.colList.splice(this.colIndex, 0, ColumnComponent); 
    this.colIndex++; 
    } 

    removeColumn(colIdx: number) { 
    this.colList.splice(colIdx, 1); 
    } 
} 

@Component({ 
    moduleId: module.id, 
    selector: 'my-column', 
    templateUrl: 'column.component.html', 
    styles: [ 
    `.col:hover { 
     border: 3px solid #304ffe; 
     } 
    ` 
    ] 
}) 

export class ColumnComponent { 

} 

@Component({ 
    moduleId: module.id, 
    selector: 'my-designer', 
    templateUrl: 'designer.component.html', 
}) 

export class DesignerComponent { 
    @ViewChild('builder') builder:ElementRef; 

    elementIndex: number = 0; 

    list: Object[] = []; 


    ngAfterViewInit() { 

    } 

    addRow() { 
    this.list.splice(this.elementIndex, 0, RowComponent); 

    this.elementIndex++; 
    } 

    remove(idx: number) { 
    this.list.splice(idx, 1); 
    } 

} 

DesignerComponent.html

<div #builder class="row"> 
    <div class="s1 teal lighten-2"> 
    <p class="flow-text">teste do html builder</p> 

    <div *ngFor="let row of list; let idx = index" > 
     <p class="flow-text">Linha {{idx}}</p> 
     <dcl-wrapper [type]="row"></dcl-wrapper> 

     <a class="btn-floating btn-small waves-effect waves-light purple" (click)="remove(idx)"><i class="material-icons">remove</i></a> 
    </div> 

    </div> 

</div> 
<a class="btn-floating btn-large waves-effect waves-light red" (click)="addRow()"><i class="material-icons">add</i></a> 

RowComponent.html

<div #row class="row"> 
    <div class="s12 teal lighten-2"> 
    <p class="flow-text">adicionando linha no html builder</p> 
    </div> 
    <div *ngFor="let col of colList; let colIndex = index"> 
    <p>Column</p> 
    <dcl-wrapper [type]="col"></dcl-wrapper> 
    </div> 
    <a class="btn-floating btn-small waves-effect waves-light waves-teal" (click)="addColumn()"><i class="material-icons">view_column</i></a> 
</div> 

ColumnComponent.html

<div class="col s1 purple lighten-2"> 
    <p class="flow-text">column added ....</p> 
</div> 

Такой подход порождает следующую ошибку:

Expression has changed after it was checked. Previous value: 'CD_INIT_VALUE'. Current value:

ли это кто-нибудь получить эту работу как вложенная элементы?

Большое спасибо за помощь!

ответ

2

Попробуйте использовать ngAfterContentInit крюк вместо ngAfterViewInit в вашем DynWrapperComponent:

дин-wrapper.component.ts

ngAfterContentInit() { 
    this.isViewInitialized = true; 
    this.updateComponent();  
} 
+0

Благодаря тонну! Это сделал трюк! :-) – Marrone