如何以角度5

时间:2018-05-29 16:32:40

标签: angular angular5

我有几个以表格形式显示数据的组件。我想将代码重构为可重用的数据表组件,以便其他组件可以使用它而不是在每个组件中复制表。但我不知道如何创建可重用的Angular材料数据表。任何人都可以帮助我。

<div class="example-container" #TABLE> 

  <mat-table #table [dataSource]="dataSource" matSort matSortActive="locationName" matSortDirection="asc" matSortDisableClear>
    <ng-container matColumnDef="locationName">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Location Name </mat-header-cell>
      <mat-cell *matCellDef="let location"> {{location.locationName}} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="address">
      <mat-header-cell *matHeaderCellDef>Address </mat-header-cell>
      <mat-cell *matCellDef="let location"> {{location.address}} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="city">
      <mat-header-cell *matHeaderCellDef mat-sort-header> City </mat-header-cell>
      <mat-cell *matCellDef="let location"> {{location.city}} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="country">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Country </mat-header-cell>
      <mat-cell *matCellDef="let location"> {{location.country}} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="zipcode">
      <mat-header-cell *matHeaderCellDef>ZipCode </mat-header-cell>
      <mat-cell *matCellDef="let location"> {{location.zipcode}} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="phone">
      <mat-header-cell *matHeaderCellDef>Phone </mat-header-cell>
      <mat-cell *matCellDef="let location"> {{location.phone}} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="timezone">
      <mat-header-cell *matHeaderCellDef> TimeZone </mat-header-cell>
      <mat-cell *matCellDef="let location"> {{location.timezone}} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="action">
      <mat-header-cell *matHeaderCellDef> Action </mat-header-cell>
      <mat-cell *matCellDef="let location">
      <a [routerLink]="['/admin/location/edit/',location.locationID]" class="btn Action-Tab">Edit</a>&nbsp;&nbsp;
      <a class="btn Action-Tab" (click)="deleteLocation(location,location.locationID)">Delete</a>
        </mat-cell>
    </ng-container>
    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let location; columns: displayedColumns;">
    </mat-row>
  </mat-table>

  <mat-paginator [pageSizeOptions]="[10, 20, 50,100]"></mat-paginator>

1 个答案:

答案 0 :(得分:0)

您可以使用接口和抽象类,泛型并与列共享.html文件。这是我用角度“@ angular / core”的一个小例子:“4.2.4”,我用它来显示数据:

文件:shared-bce-read-table.interface.ts

import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {FooterIdentifiableTotalQuantityInterface} from '../../entities/common/product-table-editable/footer-identifiable-total-quantity.interface';

/**
 * Shared interface to read data
 */
export interface SharedBceReadTableInterface<T extends FooterIdentifiableTotalQuantityInterface>{

    displayedColumns: string[];
    displayedColumnsFooter: string[];
    dataChange: BehaviorSubject<T[]>;
    data(): T[];
    dataSource: SharedBceReadDataSource<T>
}

我使用界面来识别通用T.

文件:footer-identifiable-total-quantity.interface.ts

/**
 * Interface to management total quantity sum in editing tables.
 */
export interface FooterIdentifiableTotalQuantityInterface {

    isFooterRow: boolean;

    getBalance(): number;

    getAmountBalance(): number;
}

现在是通用数据源。

文件:shared-bce-read-data-source.component.ts

import {MatPaginator, MatSort} from '@angular/material';
import {Observable} from 'rxjs/Observable';
import {DataSource} from '@angular/cdk/collections';
import {SharedBceReadTableInterface} from './shared-bce-read-table.interface';
import {FooterIdentifiableTotalQuantityInterface} from '../../entities/common/product-table-editable/footer-identifiable-total-quantity.interface';

/**
 * SharedRead, for this auxiliary component, of elements for sorter must be equals to identifier columns table.
 */
export class SharedBceReadDataSource<T extends FooterIdentifiableTotalQuantityInterface> extends DataSource<T> {
    constructor(private _table: SharedBceReadTableInterface<T>, private _sort: MatSort, private _paginator: MatPaginator) {
        super();
    }

    connect(): Observable<T[]> {
        const displayDataChanges = [
            this._table.dataChange,
            this._sort.sortChange,
            this._paginator.page
        ];

        return Observable.merge(...displayDataChanges).map(() => {
            const data = this.getSortedData();

            const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
            return data.splice(startIndex, this._paginator.pageSize);
        });
    }

    disconnect() {}

    getSortedData(): T[] {
        const data = this._table.data().slice();
        if (!this._sort.active || this._sort.direction === '') { return data; }

        return data.sort((a, b) => {
            const propertyA: number|string = a[this._sort.active];
            const propertyB: number|string = b[this._sort.active];

            const valueA = isNaN(+propertyA) ? propertyA : +propertyA;
            const valueB = isNaN(+propertyB) ? propertyB : +propertyB;

            return (valueA < valueB ? -1 : 1) * (this._sort.direction === 'asc' ? 1 : -1);
        });
    }
}

现在我们可以在每个希望显示数据的组件中实现这些类。

import {Component, Inject, OnInit, ViewChild} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef, MatPaginator, MatSort} from '@angular/material';
import {JhiAlertService, JhiEventManager} from 'ng-jhipster';
import {LoadingOverlayService} from '../../../core/loading-overlay/loading-overlay.service';
import {
    DEFAULT_ID_SORT,
    ITEMS_PER_PAGE,
    PAGE_SIZE_OPTIONS,
    ResponseWrapper,
    SharedBceReadDataSource,
    SharedBceReadTableInterface,
    START_PAGE
} from '../../../shared';
import {ProductOrderBce} from '../../product-order/product-order-bce.model';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {ProductOrderBceService} from '../../product-order';

@Component({
    selector: 'jhi-order-detail-product-purchase-order',
    templateUrl: 'order-detail-product-purchase-order.html'
})
export class OrderDetailProductPurchaseOrderComponent implements OnInit, SharedBceReadTableInterface<ProductOrderBce> {

    displayedColumns = ['purchaseOrderFolio', 'productKey', 'description', 'unitMeasureKey', 'quantity', 'unitPrice', 'amount'];
    displayedColumnsFooter = [];
    dataChange: BehaviorSubject<ProductOrderBce[]> = new BehaviorSubject<ProductOrderBce[]>([]);
    authorities: any[];
    dataSource: SharedBceReadDataSource<ProductOrderBce> = null;
    pageSizeOptions = PAGE_SIZE_OPTIONS;
    itemsPerPage = ITEMS_PER_PAGE;
    totalAmount = 0;
    totalQuantity = 0;

    @ViewChild(MatSort) sortComponent: MatSort;
    @ViewChild(MatPaginator) paginatorComponent: MatPaginator;

    constructor(
        private dialogRef: MatDialogRef<OrderDetailProductPurchaseOrderComponent>,
        @Inject(MAT_DIALOG_DATA) public dataDialog: any,
        private service: ProductOrderBceService,
        private eventManager: JhiEventManager,
        private alertService: JhiAlertService,
        protected loadingService: LoadingOverlayService
    ) {}

    ngOnInit() {
        this.authorities = ['ROLE_USER', 'ROLE_ADMIN'];
        this.dataChange.subscribe((data) => {
            data.forEach((row) => {
                this.totalQuantity += row.quantity;
                this.totalAmount += row.amount;
            });
        }, (error) => {
            this.totalAmount = 0;
            this.totalQuantity = 0;
        });
        this.dataSource = new SharedBceReadDataSource<ProductOrderBce>(this, this.sortComponent, this.paginatorComponent);
        this.loadingService.startLoading();
        this.service.searchByOrigenOrder({page: START_PAGE, size: ITEMS_PER_PAGE, sort: DEFAULT_ID_SORT,
            orderId: this.dataDialog.orderId, orderVersion: this.dataDialog.orderVersion, productId: this.dataDialog.productId}).subscribe(
            (res: ResponseWrapper) => {
                this.dataChange.next(res.json.items);
                this.loadingService.stopLoading();
            },
            (res: ResponseWrapper) => {
                this.dataChange.next([]);
                this.onError(res.json());
                this.loadingService.stopLoading();
            }
        );
    }

    onError(error) {
        this.alertService.error(error.message, null, null);
    }

    onCloseCancel() {
        this.dialogRef.close();
    }

    public data(): ProductOrderBce[] {
        return this.dataChange.value;
    }

}

产品订单必须实现FooterIdentifiableTotalQuantityInterface接口才能与表兼容。

<强>产品阶bce.model.ts

import { BaseEntity } from './../../shared';
import {EventEmitter} from '@angular/core';
import {IdentifiableProductI, ProductEditableI} from '../common';
import {FooterIdentifiableTotalQuantityInterface} from '../common/product-table-editable/footer-identifiable-total-quantity.interface';

export class ProductOrderBce implements BaseEntity, IdentifiableProductI, FooterIdentifiableTotalQuantityInterface {
    id: number = null;
    isFooterRow = false;

    constructor(
        id?: number,
        public quantity?: number,
        public balance?: number,
        public unitPrice?: number,
        public amount?: number,
        public amountBalance?: number,
        public totalRecivedQuantity?: number,
        public productId?: number,
        public unitMeasureId?: number,
        public productsOrderId?: number,
        public productsOrderVersion?: number,
        public productsOrderFolio?: string,
        public productDescription?: string,
        public unitMeasureDescription?: string,
        public unitMeasureKey?: string,
        public productKey?: string,
        public origenProductOrderId?: number,
        public origenProductOrderQuantity?: number,
        public origenProductOrderReceivedQuantity?: number
    ) {
        this.quantity = 0;
        this.unitPrice = 0;
        this.amount = 0;
        this.totalRecivedQuantity = 0;
        this.id = id;
    }

    getId(): any {
        return this.id;
    }

    getProductKey(): string {
        return this.productKey;
    }

    getProductDescription(): string {
        return this.productDescription;
    }

    getBalance() {
        return this.quantity - this.totalRecivedQuantity;
    }

    getAmountBalance() {
        return this.getBalance() * this.unitPrice;
    }

}

如果您观察到显示表的逻辑,那么您只需要为每个案例包含该文件。 html,完成显示的列,我在这里使用了材质角。我希望,这可以帮助你,同样的事情发生在我和我用来显示任何对象的详细视图的这些类。