Как создать повторно используемый компонент для таблицы данных углового материала в угловых 5 - PullRequest
0 голосов
/ 29 мая 2018

У меня есть пара компонентов, которые отображают данные в виде таблицы.Я хочу реорганизовать код в компонент таблицы данных многократного использования, чтобы другие компоненты могли использовать его вместо дублирования таблицы в каждом компоненте. Но я не уверен, как создать таблицу данных углового материала многократного использования.Может кто-нибудь, пожалуйста, помогите мне с этим.

<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 голосов
/ 29 мая 2018

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...