Dynamically loading columns and data in to table in Angular 2

后端 未结 7 878
醉话见心
醉话见心 2020-12-19 09:18

I have an HTML page in which I want to create a table. The columns in this table are dynamic which means that they are fetched from the server into a variable in the compone

相关标签:
7条回答
  • 2020-12-19 09:45

    in Angular2 Beta version:

    grid.html

    <mat-table #table [dataSource]="dataSource">
      <ng-container [matColumnDef]="columnName" *ngFor="let columnName of displayedColumns">
        <mat-header-cell *matHeaderCellDef> {{columnName}} </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element[columnName]}} </mat-cell>
      </ng-container>
    
      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
    </mat-table>
    

    grid.ts

    export class GridDynamicComponent {
      rows = new Array<CorporateEmployee>();
      dataSource: any;
      displayedColumns = [];
      yourFunction(...) {
        rows = ... // Update your model
        this.displayedColumns = rows.length > 0 ? Object.keys(rows[0]) : [];
        this.dataSource = new MatTableDataSource(rows);
      }
    }
    
    0 讨论(0)
  • 2020-12-19 09:50

    My solution is use Input() to give column and rows as array into data table component, it only renders that columns and rows i want to see:

    in component:

      @Input('cols')
      set cols(value: string){
        this._cols = value;
      }
      get cols(){
        return this._cols;
      }
    
      Input('rows')
      set rows(value: string){
        this._rows = value;
      }
      get rows(){
        return this._rows;
      }
    

    in view:

    <app-data-table *ngIf="hotels"
                      [cols]="['Hotel Name','Status','Phone','Actions']"
                      [rows]="['HotelListTitle','HotelListSaleActive','HotelListPhone']"
                      [data]="hotels"
                      [excelData]="excelData"></app-data-table>
    
    0 讨论(0)
  • 2020-12-19 09:53

    My Solution for this problem is Write This Code in Html File

    Write This Code in Ts File

    <table>
    <thead>
      <th *ngFor="let item of header">
        {{item}}
      </th>
    </thead>
    <tbody>
      <tr *ngFor="let record of test">
        <td *ngFor="let key of header">
          {{record[key]}}
        </td>
      </tr>
    </tbody>
    

    0 讨论(0)
  • 2020-12-19 09:55

    Here's my solution for Angular 5.x+:

    <div class="table-responsive">
        <table class="table">
          <thead>
            <tr>
              <th *ngFor="let cols of columnsData">{{ cols.displayName }}</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let data of tableData" > 
              <td *ngFor="let col of columnsData">
                <input [(ngModel)]="data[col.name]" type="text" />
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    

    Assuming you have columnsData set up like [{displayName: 'First Name', name: 'name'}, {displayName: 'Last Name', name: 'surname'}] Of course, you can customize those however you need.

    You can just interpolate {{ data[col.name] }} instead of using the <input> tag if you don't your fields to be editable.

    0 讨论(0)
  • 2020-12-19 10:01

    This is for those who don't want table

    Header model:

    public tempData: any[] = [{
      header: 'Import',
      field: 'import'
    }, {
      header: 'Receive:',
      field: 'receive'
    }, {
      header: 'Send',
      field: 'send'
    }],
    

    Actual data:

    public actaulData: any[] = [
    { send: 'send to data', import: 'import data', receive: 'receive data'}]
    

    View:

    <section class="p-grid p-col-12 p-nogutter" *ngFor="let data of actaulData">
          <h6 class="p-col-4 border-right">
            <div *ngFor="let item of tempData">
              <p>
                <strong>{{ item.header }}</strong>: {{ data[item.field] }}
              </p>
            </div>
          </h6>
    

    0 讨论(0)
  • 2020-12-19 10:03

    It can be used in Angular 2, 5, 6, 7. We should create a component, so that it can be used anytime, with any kind of data. I have tested it and is working.

    File : dynamic-table.component.ts

    import { Component, OnInit, Input, Output, OnChanges, SimpleChanges } from '@angular/core';
    
    @Component({
      selector: 'dynamic-table',
      templateUrl: './dynamic-table.component.html',
      styleUrls: ['./dynamic-table.component.scss']
    })
    export class DynamicTableComponent implements OnInit, OnChanges {
    
      @Input() tableHeads: Array<String> = new Array<String>();
      @Input() tableDatas: Array<any> = new Array<any>();
      @Input() tableColName: Array<String> = new Array<String>();
      private tableColNameGenerated: Array<String> = new Array<String>();
      private isTableColNameSet: Boolean = false;
    
      constructor() { }
    
      ngOnInit() {
    
      }
    
      ngOnChanges(changes: SimpleChanges) {
        if (changes['tableHeads']) {
          if (this.tableHeads.length > 0) {
            // console.log('tableHeads');
          }
        }
    
        if (changes['tableDatas']) {
          if (!this.isTableColNameSet) {
            if (this.tableDatas.length > 0) {
              this.tableColNameGenerated = this.getKeys(this.tableDatas[0]);
              if (!this.isHeadAndColLengthSame(this.tableHeads, this.tableColNameGenerated)) {
                console.error('Table column row is not same as with property name in self generated');
             }
            }
          }
        }
    
        if (changes['tableColName']) {
          if (this.tableColName.length > 0) {
            this.tableColNameGenerated = this.tableColName;
            this.isTableColNameSet = true;
            if (!this.isHeadAndColLengthSame(this.tableHeads, this.tableColName)) {
              console.error('Table column row is not same as with property name provided');
            }
          }
        }
      }
    
      /**
      * This method will fetch all the property name and convert it into a list of String.
      * @param {Array<String>} head Pass in the list of String, which contains table header values
      * @param {Array<String>} col Pass in the list of String, which contains column property 
      * name, which was received from Input or generated using this.getKeys()
      */
      private isHeadAndColLengthSame(head: Array<String>, col: Array<String>): Boolean {
        return (head.length === col.length);
      }
    
      /**
      * This method will fetch all the property name and convert it into a list of String.
      * @param {any} value Pass Instance of Object eg. new User()
      */
      private getKeys(value: any): Array<String> {
        return Object.keys(value);
      }
    
    }
    

    File : dynamic-table.component.html

    <table>
      <thead>
        <tr class="table-head">
          <th *ngFor="let tableHead of tableHeads">{{tableHead}}</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let tableData of tableDatas">
          <td *ngFor="let colName of tableColNameGenerated"> {{tableData[colName]}}</td>
        </tr>
      </tbody>
    </table>
    

    To implement this component call in some view file

    File : view-table.component.html

    <div>
      <dynamic-table [tableHeads]="tableHead" 
                     [tableDatas]="userDetails" 
                     [tableColName]="tableColName">
      </dynamic-table>
    </div>
    

    File : view-table.component.ts

    export class ViewTable implements OnInit{
    
      // fetch or create an Object of UserDetails type and pass it to dynamic-table
      private userDetails: Array<UserDetails>;
      // required to provide the table header, you can call an api or hard code the column name.
      private tableHead: Array<String>;  
      // optional, you can hard code the property name or just send the data of an object and dynamic-table component will figure out.
      private tableColName: Array<String>;  
    
      constructor(){
          this.tableHead = new Array<String>('Name', 'Age', 'Gender');
          // this.tableColName = new Array<String>('name', 'age', 'gender');
          this.userDetails = new Array<UserDetails>();
      }
       ngOnInit() {
          this.userDetails.push(new UserDetails('Apple', 18, 'Male'));
          this.userDetails.push(new UserDetails('Banana', 24, 'Female'));
          this.userDetails.push(new UserDetails('Mango', 34, 'Male'));
          this.userDetails.push(new UserDetails('Orange', 13, 'Female'));
          this.userDetails.push(new UserDetails('Guava', 56, 'Male'));
       }
    }
    
    export class UserDetails{
        constructor(public name: String, public age: Number, public gender: String) { }
    }
    
    0 讨论(0)
提交回复
热议问题