简体   繁体   中英

Reading components inside an Angular4 template / directive

I am working on a grid component which is composed of mainly three things, some GridComponent component which takes in an array data source, a RowItem directive which is only responsible of creating a context for a row, and a ColumnComponent which is the definition of the column's content.

In a nutshell, the usage of the component looks like this:

<my-grid [data-source]="dataSource">
    <ng-container *rowItem="let item">
        <my-column column-header="Person">
            {{item.name}}
        </my-column>

        <my-column column-header="Age">
            {{item.age}}
        </my-column>

        <my-column column-header="Car">
            {{item.car}}
        </my-column>
    </ng-container>
</my-grid>

Now, my columns are defined like this :

<ng-container *ngIf="someConditionHere">
  <ng-content></ng-content>
</ng-container>

which will collect the content specified by the developer and pass onto the grid, which in turn will take care of rendering the complete control, as seen in the template below.

<table>
  <thead>
    <tr>
      <th *ngFor="let col of columns">
        {{col.columnHeader}}
      </th>
    </tr>
  </thead>
  <tbody>
    <tr class="core-grid-row" *ngFor="let row of dataSource">
      <ng-template [ngTemplateOutlet]="rowItem" [ngOutletContext]="{$implicit: row}"></ng-template>
    </tr>
  </tbody>
</table>

The problem I have now is related to rendering the column names. I am trying to collect the names using the ContentChildren below

@ContentChildren(ColumnComponent)
public columns: QueryList<ColumnComponent>;

However since there is the *ngFor directive in the grid, my ContentChildren query is gathering the columns multiplied by the number of rows, instead of only the first row. Is there someway I can gather the column names without the side effects of the *ngFor in a clean and neat manner?

Thanks for your time!

What you could do is to Tag the columns in the first row

 <tr class="core-grid-row" *ngFor="let row of dataSource; let i = index">
      <ng-template [ngTemplateOutlet]="rowItem" [ngOutletContext]="{$implicit: row, 'i: i}"></ng-template>
 </tr>

(I'm not quite sure about the codestyle for passing the index throuh with ngOutletContext,... maybe it is a little bit diffrent)

and then you could tag the first columns with the use of the index:

   <ng-container *ngIf="i == 0 && someConditionHere" #headerColumn>
      <ng-content></ng-content>
   </ng-container>
   <ng-container *ngIf="i > 0 && someConditionHere">
      <ng-content></ng-content>
   </ng-container>

then you should be able to grab just the first line of columns by:

@ContentChildren(#headerColumn)
public columns: QueryList<ColumnComponent>;

I managed to fix this in a way by wrapping the container in a my-row component rather than an ng-container . Like this I could access the components directly. However still used the directive for creating a context variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM