Вы можете использовать интерфейсы и абстрактные классы, обобщения и обмениваться файлами .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-amount.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 для совместимости с таблицей.
product-order-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, заполните отображаемые столбцы, я использовал материал угловой.Я надеюсь, и это может помочь вам, то же самое случилось со мной и этими классами, которые я использую, чтобы показать детальные виды любого объекта.