首页 > 解决方案 > 实现表的通用组件

问题描述

我有一个前端应用程序,我在其组件中经常使用表。然后我决定为表格编写一个通用组件。

首先我为表格中的每个单元格编写一个模型:

export class MemberTable {
  public content: string;
  public type: string; // type --> [text, html, hyperlink, routerlink, button, hidden]
  public functionNum: number;
  public address: string;
  public queryParams: {};
  public cssClass: string;

  constructor(content = '', type = 'text', address = null, queryParams = null, functionNum = 0, cssClass = null) {
    this.content = content;
    this.type = type;
    this.address = address;
    this.queryParams = queryParams;
    this.functionNum = functionNum;
    this.cssClass = cssClass;
  }
}

内容:单元格的内容

类型:一个单元格有不同的类型。例如,它可以是链接、文本或按钮。

其他属性可以根据类型属性具有值。

表组件:

ts文件:

import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { MemberTable } from '../../../models/member-table.model';

@Component({
  selector: 'app-lenard-table',
  templateUrl: './lenard-table.component.html',
  styleUrls: ['./lenard-table.component.css']
})
export class LenardTableComponent implements OnInit {

  @Input() headTable: any[] = [];
  @Input() bodyTable: Array < Array < MemberTable >> = new Array < Array < MemberTable >> ();

  @Output() function1 = new EventEmitter < any > ();
  @Output() function2 = new EventEmitter < any > ();
  @Output() function3 = new EventEmitter < any > ();

  constructor(private comm: LoggedUserBaseListComponent) {}

  ngOnInit() {}


  onFunction1() {
    this.function1.emit(true);
  }

  onFunction2() {
    this.function2.emit(true);
  }

  onFunction3() {
    this.function3.emit(true);
  }

}

.html 文件

<div class="table-responsive">
  <table 
    class="table table-hover text-center" 
    style="border: 2px solid #DADADE;">
    <thead>
      <tr class="middle-blue">
        <th *ngFor="let text of headTable" 
          class="lenard-th" 
          [innerHtml]="text">
        </th>
      </tr>
    </thead>

    <tbody>
      <tr 
        *ngFor="let memberArr of bodyTable" 
        style="border-top: 2px solid #949496;">

        <ng-container *ngFor="let member of memberArr">
          <td *ngIf="member.type == 'text'">{{ member.content }}</td>

          <td *ngIf="member.type == 'routerlink'">
            <a 
              [routerLink]="member.address" 
              [queryParams]="member.queryParams" 
              [ngClass]="member.cssClass">
              {{ member.content }}
            </a>
          </td>

          <td *ngIf="member.type == 'hyperlink'">
            <a 
              [href]="member.address" 
              [ngClass]="member.cssClass">
              {{ member.content }}
            </a>
          </td>

          <td *ngIf="member.type == 'button'">
            <button 
              *ngIf="member.functionNum == 1" 
              [ngClass]="member.cssClass" 
              (click)="onFunction1()">
              {{ member.content }}
            </button>
            <button 
              *ngIf="member.functionNum == 2" 
              [ngClass]="member.cssClass" 
              (click)="onFunction2()">
              {{ member.content }}
            </button>
            <button 
              *ngIf="member.functionNum == 3" 
              [ngClass]="member.cssClass" 
              (click)="onFunction3()">
              {{ member.content }}
            </button>
          </td>

          <td 
            *ngIf="member.type == 'html'" 
            [innerHtml]='member.content'>
          </td>
        </ng-container>

      </tr>
    </tbody>
  </table>
</div>

我想知道,这种方法是否正确?

编辑:

我可以在其他组件中使用表格组件,如下所示:

this.headTable = ['#', 'Analyzer Model', 'Serial No.', 'Ava. Credits', 'Total Tests',
                  'Passed Tests', 'Failed Tests', 'Adapters', ' '];


this.bodyTable.push([new MemberTable(index.toString(), 'text'),
                                new MemberTable(ub.id, 'hidden'),
                                new MemberTable(ub.base_version, 'text'),
                                new MemberTable(ub.serialNumber, 'text'),
                                new MemberTable('12121', 'routerlink', '/controlpanel/customer/mycredit/1/list'),
                                new MemberTable(ub.totalReportCount, 'routerlink', '/controlpanel/customer/analyzer/info/' + user_base.id + '/test/list', {'select': 'total'}),
                                new MemberTable(ub.passedReportCount, 'routerlink', '/controlpanel/customer/analyzer/info/' + user_base.id + '/test/list', {'select': 'passed'}),
                                new MemberTable(ub.failedReportCount, 'routerlink', '/controlpanel/customer/analyzer/info/' + user_base.id + '/test/list', {'select': 'failed'}),
                                new MemberTable(ub.adapterCount, 'routerlink', '/controlpanel/customer/analyzer/info/' + user_base.id + '/adapterlist'),
                                new MemberTable('Add Credits', 'button', null, null, 1, 'btn btn-round btn-orange btn-xs')
                              ])


<app-lenard-table [headTable]="headTable" [bodyTable]="bodyTable" 
    (function1)="goAct()">

标签: htmlangulartypescript

解决方案


这实际上取决于您的需求。如果您想要快速有效的解决方案 - 这对您来说就足够了。然而,为了提高可重用性,最好为每个行类型组件创建并根据当前行渲染动态添加它。还有另一种方法,只是不要重新发明轮子——Data Grids例如Angular Material Data Grid。数据网格具有许多优点,例如sortingpagination等等,它们还有很多,但它们不是免费的。


推荐阅读