3

i am trying to build hierarchical grid in angular2 with n-child grids.

My markup should look something like this

<grid [observable]="users$">
    <column key="Username" caption="Username"></column>
    <column key="Name" caption="Name"></column>

    <grid property="UserGroups">
        <column key="GroupNo" caption="Group-No"></column>        
    </grid>
</grid>

Here is my component:

@Component({
    selector: 'grid',
    directives: [FORM_DIRECTIVES, Column],
    template: `
        <table class="table table-grid">
            <thead>
                <tr>
                    <th *ngIf="childGrid"></th>
                    <th *ngFor="#col of columns" [attr.key]="col.ColumnKey">
                        {{ col.Caption }}
                    </th>
                </tr>
            </thead>
            <tbody>
                <template ngFor #item [ngForOf]="data">                    
                    <tr>
                        <td *ngIf="childGrid" (click)="setChildData(item)">
                        </td>
                        <td *ngFor="#col of columns" [attr.key]="col.ColumnKey">
                            {{ item[col.ColumnKey] }}
                        </td>
                    </tr>
                    <tr *ngIf="childGrid" class="child-container">
                        <td></td>
                        <td [attr.colspan]="columns.length">
                            <ng-content select="grid"></ng-content>
                        </td>
                    </tr>
                </template>
            </tbody>
        </table>
    `
})
export class Grid {

    private _initialized: boolean = false;

    @Input('observable') obs$: Observable<any[]>;        
    @Input('property') propertyName: string;

    @ContentChildren(Column, false) columns: QueryList<Column>;
    @ContentChildren(Grid, true) childs: QueryList<Grid>;

    data: any[] = [];
    get childGrid(): Grid {
        if (this.childs.length == 0) return null;

        return this.childs.filter(x => x != this)[0];
    }
    htmlNode: HTMLElement;

    constructor(elementRef: ElementRef) {
        this.htmlNode = <HTMLElement>elementRef.nativeElement;
    }

    ngOnInit() {
        if (this.obs$ != null) this.obs$.subscribe(data => this.data = data);
    }

    setChildData(data: any) {
        if (data != null && this.childGrid != null) {
            var prop = this.childGrid.propertyName;

            this.childGrid.data = data[prop]
        }
    }
}

My problem now is that the child-grid gets only rendered once. Is there a way to render it for every loop?

NQuirmbach
  • 31
  • 2

1 Answers1

2

If you have multiple <ng-content> with the same selector, the content is only projected the first one. This is by design (probably to align with the web-components <content> tag). Content also can only projected once, even when several selectors match.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Is there any approach to solve this problem? I am kinda lost right now. hwo to solve this problem. – NQuirmbach Jan 29 '16 at 08:32
  • So you want to repeat content provided as children by the user of your component? I just started investigating something like that. I think building something similar to `NgFor` where a directive takes a template and renders it x times should be possible but have yet to make it work myself. The source doesn't look too complicated https://github.com/angular/angular/blob/7ae23adaff2990cf6022af9792c449730d451d1d/modules/angular2/src/common/directives/ng_for.ts#L62. The user of your component might be required to provide his content wrapped in a `` – Günter Zöchbauer Jan 29 '16 at 08:37
  • 2
    My goal is to create a grid-component that can have multiple child grids. The data can be dynamic and i need to define the columns, so i can add some options, like sortable and draggable. I guess i will try to create something similar like ngFor that i can use. – NQuirmbach Jan 29 '16 at 08:52