首页 > 解决方案 > Angular:如何将服务连接到 Material RankTable?

问题描述

我正在学习 Angular 并试图掌握这些概念。我很难做一些应该很简单的事情。

我想将材料表连接到下载一些数据的服务。

我创建了从网站下载一些简单数据的服务。我使用命令行创建了数据表。现在我必须更改我的服务的数据源。

这是生成的文件rank-table-datasource.ts

import { DataSource } from '@angular/cdk/collections';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { map } from 'rxjs/operators';
import { Observable, of as observableOf, merge } from 'rxjs';

// TODO: Replace this with your own data model type
export interface RankTableItem {
  name: string;
  id: number;
}

// TODO: replace this with real data from your application
const EXAMPLE_DATA: RankTableItem[] = [
  {id: 1, name: 'Hydrogen'},
  {id: 2, name: 'Helium'},
  {id: 3, name: 'Lithium'},
  {id: 4, name: 'Beryllium'},
  {id: 5, name: 'Boron'},
  {id: 6, name: 'Carbon'},
  {id: 7, name: 'Nitrogen'},
  {id: 8, name: 'Oxygen'},
  {id: 9, name: 'Fluorine'},
  {id: 10, name: 'Neon'},
  {id: 11, name: 'Sodium'},
  {id: 12, name: 'Magnesium'},
  {id: 13, name: 'Aluminum'},
  {id: 14, name: 'Silicon'},
  {id: 15, name: 'Phosphorus'},
  {id: 16, name: 'Sulfur'},
  {id: 17, name: 'Chlorine'},
  {id: 18, name: 'Argon'},
  {id: 19, name: 'Potassium'},
  {id: 20, name: 'Calcium'},
];

/**
 * Data source for the RankTable view. This class should
 * encapsulate all logic for fetching and manipulating the displayed data
 * (including sorting, pagination, and filtering).
 */
export class RankTableDataSource extends DataSource<RankTableItem> {
  data: RankTableItem[] = EXAMPLE_DATA;
  paginator: MatPaginator;
  sort: MatSort;

  constructor() {
    super();
  }

  /**
   * Connect this data source to the table. The table will only update when
   * the returned stream emits new items.
   * @returns A stream of the items to be rendered.
   */
  connect(): Observable<RankTableItem[]> {
    // Combine everything that affects the rendered data into one update
    // stream for the data-table to consume.
    const dataMutations = [
      observableOf(this.data),
      this.paginator.page,
      this.sort.sortChange
    ];

    return merge(...dataMutations).pipe(map(() => {
      return this.getPagedData(this.getSortedData([...this.data]));
    }));
  }

  /**
   *  Called when the table is being destroyed. Use this function, to clean up
   * any open connections or free any held resources that were set up during connect.
   */
  disconnect() {}

  /**
   * Paginate the data (client-side). If you're using server-side pagination,
   * this would be replaced by requesting the appropriate data from the server.
   */
  private getPagedData(data: RankTableItem[]) {
    const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
    return data.splice(startIndex, this.paginator.pageSize);
  }

  /**
   * Sort the data (client-side). If you're using server-side sorting,
   * this would be replaced by requesting the appropriate data from the server.
   */
  private getSortedData(data: RankTableItem[]) {
    if (!this.sort.active || this.sort.direction === '') {
      return data;
    }

    return data.sort((a, b) => {
      const isAsc = this.sort.direction === 'asc';
      switch (this.sort.active) {
        case 'name': return compare(a.name, b.name, isAsc);
        case 'id': return compare(+a.id, +b.id, isAsc);
        default: return 0;
      }
    });
  }
}

/** Simple sort comparator for example ID/Name columns (for client-side sorting). */
function compare(a: string | number, b: string | number, isAsc: boolean) {
  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}

我导入了我的服务和我的界面:

import { EscolaService } from '../escola.service'
import { Escola } from '../escola';

我的界面也只有一个id和一个name,就像原来的一样。

为我的类型定义了一个别名。不知道这是否是正确的方法:

export type RankTableItem = Escola;

我现在应该重新定义connect()方法:

connect(): Observable<RankTableItem[]> {

但我不知道该怎么做。

rank-table-component.html尝试使用一些 dataSource 方法:

  <mat-paginator #paginator
      [length]="dataSource?.data.length"
      [pageIndex]="0"
      [pageSize]="50"
      [pageSizeOptions]="[25, 50, 100, 250]">

我应该如何使用这个连接方法和我的服务生成的观察者?

标签: angularangular-materialangular-services

解决方案


您可以使用自己的数据源,如下所示

一个。这是您定义的自定义数据源。

export class RankTableDataSource extends DataSource<RankTableItem> {

  //Your rest of the code with connect() and disconnect() methods.

}

湾。然后您可以在组件中使用上述数据源,例如

export class YourComponent implements OnInit, AfterViewInit {

    //Take your data source into data bound property
    dataSource: RankTableDataSource;

    constructor(  ) {}


    //Initialize your data source in onInit method
    ngOnInit() {
        this.dataSource = new RankTableDataSource();
    }    
}

C。然后将其dataSource用于您的模板。

由 mat-table 数据源自动调用的connect()and方法。disconnect()如果您使用自定义数据源,则无需手动将这些方法调用到您自己的代码中。


推荐阅读