Подтвердить что ты не робот

Как использовать таблицу данных material2

Я пытаюсь реализовать таблицу данных Material2. Но я не могу понять, как правильно использовать его.

import {Component, ElementRef, ViewChild} from '@angular/core';
import {DataSource} from '@angular/cdk';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/observable/fromEvent';

@Component({
  selector: 'table-filtering-example',
  styleUrls: ['table-filtering-example.css'],
  templateUrl: 'table-filtering-example.html',
})
export class TableFilteringExample {
  displayedColumns = ['userId', 'userName', 'progress', 'color'];
  exampleDatabase = new ExampleDatabase();
  dataSource: ExampleDataSource | null;

  @ViewChild('filter') filter: ElementRef;

  ngOnInit() {
    this.dataSource = new ExampleDataSource(this.exampleDatabase);
    Observable.fromEvent(this.filter.nativeElement, 'keyup')
        .debounceTime(150)
        .distinctUntilChanged()
        .subscribe(() => {
          if (!this.dataSource) { return; }
          this.dataSource.filter = this.filter.nativeElement.value;
        });
  }
}

/** Constants used to fill up our data base. */
const COLORS = ['maroon', 'red', 'orange', 'yellow', 'olive', 'green', 'purple',
  'fuchsia', 'lime', 'teal', 'aqua', 'blue', 'navy', 'black', 'gray'];
const NAMES = ['Maia', 'Asher', 'Olivia', 'Atticus', 'Amelia', 'Jack',
  'Charlotte', 'Theodore', 'Isla', 'Oliver', 'Isabella', 'Jasper',
  'Cora', 'Levi', 'Violet', 'Arthur', 'Mia', 'Thomas', 'Elizabeth'];

export interface UserData {
  id: string;
  name: string;
  progress: string;
  color: string;
}

/** An example database that the data source uses to retrieve data for the table. */
export class ExampleDatabase {
  /** Stream that emits whenever the data has been modified. */
  dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]);
  get data(): UserData[] { return this.dataChange.value; }

  constructor() {
    // Fill up the database with 100 users.
    for (let i = 0; i < 100; i++) { this.addUser(); }
  }

  /** Adds a new user to the database. */
  addUser() {
    const copiedData = this.data.slice();
    copiedData.push(this.createNewUser());
    this.dataChange.next(copiedData);
  }

  /** Builds and returns a new User. */
  private createNewUser() {
    const name =
        NAMES[Math.round(Math.random() * (NAMES.length - 1))] + ' ' +
        NAMES[Math.round(Math.random() * (NAMES.length - 1))].charAt(0) + '.';

    return {
      id: (this.data.length + 1).toString(),
      name: name,
      progress: Math.round(Math.random() * 100).toString(),
      color: COLORS[Math.round(Math.random() * (COLORS.length - 1))]
    };
  }
}

/**
 * Data source to provide what data should be rendered in the table. Note that the data source
 * can retrieve its data in any way. In this case, the data source is provided a reference
 * to a common data base, ExampleDatabase. It is not the data source responsibility to manage
 * the underlying data. Instead, it only needs to take the data and send the table exactly what
 * should be rendered.
 */
export class ExampleDataSource extends DataSource<any> {
  _filterChange = new BehaviorSubject('');
  get filter(): string { return this._filterChange.value; }
  set filter(filter: string) { this._filterChange.next(filter); }

  constructor(private _exampleDatabase: ExampleDatabase) {
    super();
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<UserData[]> {
    const displayDataChanges = [
      this._exampleDatabase.dataChange,
      this._filterChange,
    ];

    return Observable.merge(...displayDataChanges).map(() => {
      return this._exampleDatabase.data.slice().filter((item: UserData) => {
        let searchStr = (item.name + item.color).toLowerCase();
        return searchStr.indexOf(this.filter.toLowerCase()) != -1;
      });
    });
  }

  disconnect() {}
}

Выше код кода, который очень запутан для меня. Даже их документация очень бедна. Может кто-нибудь объяснить, что такое поток выше кода?

Пожалуйста, проигнорируйте, если вы считаете, что вопрос слишком простой, чтобы спросить?

4b9b3361

Ответ 1

Код из вашего примера - это определение общей таблицы с использованием нового компонента cdk в спецификации material2. вы должны иметь в виду, что md-table - это визуальная реализация cdk-table, поэтому вам нужно объявить cdk с моделью, совместимой с md-моделью в HTML.

Например:

Объявляю cdk-table со следующей реализацией:

  • Во-первых, зависимости:

Новый компонент CDK в Material2, используя:

import { DataSource } from '@angular/cdk';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
  • Определение структуры HTML в TS:

Я определяю массив displayedColumns, элементы - это столбцы в моей таблице HTML, чтобы:

displayedColumns = ['userId', 'userName', 'progress'];

База данных типа ExampleDatabase (объект с конкретным руководством):

exampleDatabase = new ExampleDatabase();

Наконец, я объявляю dataSource, это источник моих данных. Это объект с ручным определением или нулевым значением.

dataSource: ExampleDataSource | null;

В методе ngOnInit() я просто объявляю, что мой dataSource является новым ExampleDataSource с параметром my ExampleDatabase.

Хорошо, теперь для реализации остальной части кода:

Сначала объявите интерфейс для DataBase. Это очень важно для поддержания конгруэнтности данных, база данных должна соблюдать определенную схему. В этом примере база данных содержит три столбца: id, имя и прогресс:

export interface UserData {
  id: number;
  name: string;
  progress: string;
}

Следующим пунктом является создание класса (Object) ExampleDatabase с определением данных в моем DataBase. Вы можете создать сервис для подключения к фактической базе данных (PostgreSQL, MongoDB), получить реальные данные и создать объекты для cdk-datatable в другом методе, однако в этом примере мы используем базу данных памяти, эмулируемую во время выполнения.

export class ExampleDatabase {
  /** Stream that emits whenever the data has been modified. */
  dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]);
  get data(): UserData[] { return this.dataChange.value; }

  constructor() {
    // Fill up the database with 100 users.
    for (let i = 0; i < 100; i++) { this.addUser(); }
  }

  /** Adds a new user to the database. */
  addUser() {
    const copiedData = this.data.slice();
    copiedData.push(this.createNewUser());
    this.dataChange.next(copiedData);
  }

  /** Builds and returns a new User. */
  private createNewUser() {

    return {
      id: 1,
      name: 'example',
      progress: Math.round(Math.random() * 100).toString()
    };
  }
}

Хорошо, наконец, создаю второй класс с определением my dataSource.

export class ExampleDataSource extends DataSource<any> {
  constructor(private _exampleDatabase: ExampleDatabase) {
    super();
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<UserData[]> {
    return this._exampleDatabase.dataChange;
  }

  disconnect() { }
}

Этот метод гарантирует, что данные находятся в правильном формате и освобождает "соединение" с DataBase (в памяти), чтобы получить в нем данные.

Наконец, используйте компонент md-table или cdk-table в HTML. Компонент md-table использует стиль дизайна материала, а cdk-table использует общий стиль.

мкр-таблицы:

<div class="example-container mat-elevation-z8">
  <md-table #table [dataSource]="dataSource">

    <!-- ID Column -->
    <ng-container cdkColumnDef="userId">
      <md-header-cell *cdkHeaderCellDef> ID </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.id}} </md-cell>
    </ng-container>

    <!-- Progress Column -->
    <ng-container cdkColumnDef="progress">
      <md-header-cell *cdkHeaderCellDef> Progress </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.progress}}% </md-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container cdkColumnDef="userName">
      <md-header-cell *cdkHeaderCellDef> Name </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.name}} </md-cell>
    </ng-container>

    <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
    <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>
  </md-table>
</div>

CDK-таблицы:

<div class="example-container mat-elevation-z8">
  <cdk-table #table [dataSource]="dataSource" class="example-table">

    <!-- ID Column -->
    <ng-container cdkColumnDef="userId">
      <cdk-header-cell *cdkHeaderCellDef class="example-header-cell"> ID </cdk-header-cell>
      <cdk-cell *cdkCellDef="let row" class="example-cell"> {{row.id}} </cdk-cell>
    </ng-container>

    <!-- Progress Column -->
    <ng-container cdkColumnDef="progress">
      <cdk-header-cell *cdkHeaderCellDef class="example-header-cell"> Progress </cdk-header-cell>
      <cdk-cell *cdkCellDef="let row" class="example-cell"> {{row.progress}}% </cdk-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container cdkColumnDef="userName">
      <cdk-header-cell *cdkHeaderCellDef class="example-header-cell"> Name </cdk-header-cell>
      <cdk-cell *cdkCellDef="let row" class="example-cell"> {{row.name}} </cdk-cell>
    </ng-container>

    <cdk-header-row *cdkHeaderRowDef="displayedColumns" class="example-header-row"></cdk-header-row>
    <cdk-row *cdkRowDef="let row; columns: displayedColumns;" class="example-row"></cdk-row>
  </cdk-table>
</div>

Остальные реализации, поиск, меню, флажки и т.д. - это ваша ответственность за реализацию логики для управления информацией.

Для получения дополнительной информации используйте документацию о cdk-таблице:

https://material.angular.io/guide/cdk-table

Результат:

введите описание изображения здесь

Сделай мне саблей и достижения, я понимаю свое объяснение, и я прошу прощения за мой английский. Я учусь.

Ответ 2

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

app.component.ts

import { Component, OnInit, ElementRef, ViewEncapsulation, ViewChild } from '@angular/core';
import { DataSource } from '@angular/cdk';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { MdPaginator, MdSort } from '@angular/material';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
declare let d3: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})


export class AppComponent implements OnInit {

  displayedColumns = ['shiftDate', 'swipeIn', 'swipeOut', 'duration', 'status'];
  exampleDatabase = new ExampleDatabase();
  dataSource: ExampleDataSource | null;

  @ViewChild(MdPaginator) paginator: MdPaginator;
  @ViewChild(MdSort) sort: MdSort;

  ngOnInit() {
    this.dataSource = new ExampleDataSource(this.exampleDatabase, this.paginator, this.sort);
  }
}

export interface attendanceData {
  shiftDate: string;
  swipeIn: string;
  swipeOut: string;
  duration: string;
  status: string;
}


/** An example database that the data source uses to retrieve data for the table. */
export class ExampleDatabase {
  /** Stream that emits whenever the data has been modified. */
  dataChange: BehaviorSubject<attendanceData[]> = new BehaviorSubject<attendanceData[]>([]);
  get data(): attendanceData[] {

    let data = [
      {
        "shiftDate": "17-July-2017",
        "swipeIn": "10:00 AM",
        "swipeOut": "06:00 PM",
        "duration": "8 Hours",
        "status": "PRESENT"

      },
      {
        "shiftDate": "16-July-2017",
        "swipeIn": "9:00 AM",
        "swipeOut": "5:00 AM",
        "duration": "7 Hours",
        "status": "PRESENT"
      }

    ];

    return data;
  }

  constructor() {

    this.dataChange.next(this.data);
  }

}

export class ExampleDataSource extends DataSource<any> {
  _filterChange = new BehaviorSubject('');
  get filter(): string { return this._filterChange.value; }
  set filter(filter: string) { this._filterChange.next(filter); }

  constructor(private _exampleDatabase: ExampleDatabase, private _paginator: MdPaginator, private _sort: MdSort) {
    super();
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<attendanceData[]> {
    const displayDataChanges = [
      this._exampleDatabase.dataChange,
      this._paginator.page,
      this._sort.mdSortChange
    ];

    return Observable.merge(...displayDataChanges).map(() => {
      // const data = this._exampleDatabase.data.slice();
      const data = this.getSortedData();
      // Grab the page slice of data.
      const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
      return data.splice(startIndex, this._paginator.pageSize);
    });
  }

  disconnect() { }

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

    return data.sort((a, b) => {
      let propertyA: number | string = '';
      let propertyB: number | string = '';

      switch (this._sort.active) {
        case 'shiftDate': [propertyA, propertyB] = [a.shiftDate, b.shiftDate]; break;
        case 'swipeIn': [propertyA, propertyB] = [a.swipeIn, b.swipeIn]; break;
        case 'swipeOut': [propertyA, propertyB] = [a.swipeOut, b.swipeOut]; break;
        case 'duration': [propertyA, propertyB] = [a.duration, b.duration]; break;
      }

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

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

app.component.html

<div class="example-container mat-elevation-z8">
  <md-table #table [dataSource]="dataSource" mdSort>
    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

    <!-- ID Column -->
    <ng-container cdkColumnDef="shiftDate">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Shift Date </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.shiftDate}} </md-cell>
    </ng-container>

    <!-- Progress Column -->
    <ng-container cdkColumnDef="swipeIn">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Swipe In </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.swipeIn}}% </md-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container cdkColumnDef="swipeOut">
      <md-header-cell *cdkHeaderCellDef> Swipe Out </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.swipeOut}} </md-cell>
    </ng-container>

    <!-- Color Column -->
    <ng-container cdkColumnDef="duration">
      <md-header-cell *cdkHeaderCellDef>Duration</md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.duration}} </md-cell>
    </ng-container>


    <!-- Color Column -->
    <ng-container cdkColumnDef="status">
      <md-header-cell *cdkHeaderCellDef>Status</md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.status}} </md-cell>
    </ng-container>

    <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
    <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>
  </md-table>

    <md-paginator #paginator
                [length]="exampleDatabase.data.length"
                [pageIndex]="0"
                [pageSize]="25"
                [pageSizeOptions]="[5, 10, 25, 100]">
  </md-paginator>

</div>

app.module.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { MaterialModule, MdTableModule  } from '@angular/material';
import { FlexLayoutModule } from '@angular/flex-layout';
import { CdkTableModule } from '@angular/cdk';


import { AppComponent } from './app.component';



@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserAnimationsModule,
    CdkTableModule,
    BrowserModule,
    MaterialModule, MdTableModule,
    FlexLayoutModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Ответ 3

Вот статья, написанная мной. Вы найдете все, что вам нужно знать здесь. https://medium.com/@fnote/md-tables-angular-material-be2c45947955

позволяет взять фрагмент кода по частям. Здесь вы найдете полный код https://material.angular.io/components/table/overview

import {Component} from '@angular/core';
import {DataSource} from '@angular/cdk';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';

импортируйте необходимые вам пакеты. Убедитесь, что вы устанавливаете angular cdk при установке материала angular. Прежде чем продолжить, лучше указать, что является источником данных, что является наблюдаемым, а также объектом поведения, а также rxjs.

RXJS - это горячая тема в конце концов. Это библиотека javascript для реактивного программирования (реактивное программирование - это всего лишь способ создания программных приложений. По сути, ваше программное обеспечение построено так, чтобы "реагировать" на происходящие изменения ( например, события кликов, извлечение данных и т.д.)) с использованием Observables, чтобы упростить составление асинхронного или обратного кода. cdk импортируется, потому что md-таблицы построены поверх него. Таблицы Cdk являются основой для таблиц md.

Что такое наблюдаемое?

Возможность наблюдаемых, способных обрабатывать множество значений с течением времени, делает их хорошим кандидатом для работы с данными в реальном времени, событиями и любым видом потока, о котором вы можете думать. Наблюдения обеспечивают лучший контроль при работе с потоком значений из потока. Наблюдаемый - это оболочка вокруг источника данных, источник данных - это поток значений, возможно, испускающий множество значений с течением времени, которые мы хотим что-то делать, когда возникает новое значение. Мы подключаем наблюдателя и наблюдаем через подписку. В подписке говорится, что кто-то слушает этот поток ценностей. Наблюдатель подписывается на Наблюдаемый. Наблюдатель испускает предметы или отправляет уведомления своим наблюдателям, вызывая методы наблюдателей. observer реализует до 3 методов. Они являются complete(), next() и onerror(). next() будет вызываться наблюдаемым всякий раз, когда вызывается новое значение. Когда бы ни наблюдалось, генерируется метод errorerror(), когда наблюдаемый выполняется, и когда он знает, что в будущем не будет никаких новых значений в будущем, он называет завершение().

Я настоятельно рекомендую вам ознакомиться с сериалом academy на youtube о библиотеке RXJS, чтобы получить более глубокое понимание возможностей RXJS, наблюдателей, наблюдаемых, предметов, предметов поведения и подписки.

Продолжим код

@Component({
selector: 'table-basic-example',
styleUrls: ['table-basic-example.css'],
templateUrl: 'table-basic-example.html',
})

Это регулярное angular 4.selector - это имя, по которому внешние стороны ссылаются на наш компонент .and style Url - это место, где наш/файл этот компонент ссылается на стилирование, а базовый html компонента находится в шаблоне URL-адрес.

export class TableBasicExample {
displayedColumns = ['userId', 'userName', 'progress', 'color'];
exampleDatabase = new ExampleDatabase();
dataSource: ExampleDataSource | null;
ngOnInit() {
this.dataSource = new ExampleDataSource(this.exampleDatabase);
}
}

Здесь сначала мы делаем массив всех столбцов нашей таблицы, которые нам нужно отобразить в браузере (заголовки столбцов), этот массив снова ссылается на html файл.

И далее мы создаем экземпляр класса базы данных примера и экземпляр источника данных, который не содержит данных в начале. Затем данные в базе данных примера вводятся в этот источник данных, чтобы заполнить его, поскольку он изначально пуст Ng onitint - это крючок жизненного цикла, который вызывается angular, чтобы отметить завершение создания компонента.

const COLORS = ['maroon', 'red', 'orange', 'yellow', 'olive', 'green', 
'purple','fuchsia', 'lime', 'teal', 'aqua', 'blue', 'navy', 'black', 
'gray'];
const NAMES = ['Maia', 'Asher', 'Olivia', 'Atticus', 'Amelia', 
'Jack','Charlotte', 'Theodore', 'Isla', 'Oliver', 'Isabella', 
'Jasper','Cora', 'Levi', 'Violet', 'Arthur', 'Mia', 'Thomas', 'Elizabeth'];

У нас есть 2 массива. Заполните нашу базу данных примеров

export interface UserData {
id: string;
name: string;
progress: string;
color: string;
}

Здесь вы определили интерфейс. Перечисленные здесь переменные в конечном итоге станут столбцами наших таблиц.

export class ExampleDatabase {
 dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>
([]);
get data(): UserData[] { return this.dataChange.value; }
constructor() {
// Fill up the database with 100 users.
for (let i = 0; i < 100; i++) { this.addUser(); }
}
addUser() {
const copiedData = this.data.slice();
copiedData.push(this.createNewUser());
this.dataChange.next(copiedData);
}
private createNewUser() {
const name =
NAMES[Math.round(Math.random() * (NAMES.length - 1))] + ' ' +
NAMES[Math.round(Math.random() * (NAMES.length - 1))].charAt(0) + '.';
return {
id: (this.data.length + 1).toString(),
name: name,
progress: Math.round(Math.random() * 100).toString(),
color: COLORS[Math.round(Math.random() * (COLORS.length - 1))]
};
}
}

Это пример базы данных, которую использует источник данных для извлечения данных для таблицы. У вас есть только 2 массива, но на самом деле отображаются 4 столбца. Вы можете заполнить 2 столбца из данных в массивах, но данные для других 2 столбцов здесь должны быть сгенерированы внутри этого класса.

Итак, что является предметом? Наблюдаемые не могут сами испускать ценности, но мы хотим иметь возможность сделать это сами. Но если нам нужно самим испускать новые ценности, нам нужно идти с предметом. Объект является наблюдаемым, который он наследует от наблюдаемого, но мы можем вызвать метод next() на нем вручную, чтобы мы могли инициировать излучение нового значения. Поэтому субъект является активным наблюдаемым. Он является наблюдателем в дополнение к тому, чтобы быть наблюдаемым, поэтому вы также можете отправлять значения субъекту в дополнение к подписке на него.

Что в мире является объектом поведения?Предмет поведения - это особый тип предмета, но он имеет начальное значение, в отличие от предметов. Он должен иметь начальное значение, так как он всегда должен возвращать значение для подписки, даже если он не получил следующий()   Rx.subject() подписка не получит ничего изначально   Rx.behaviorsubject( "а) подписка get 'первоначально

Не беспокойтесь о коде, написанном с именем const... у нас есть около 20 имен в массиве имен, но нам нужно 100 различных имен. Поэтому здесь мы меняем свои инициалы в произвольном шаблоне.

Прогресс также вычисляется случайным образом.

Изменение данных - это переменная типа поведения.

this.dataChange.next(copiedData); 

.. всякий раз, когда новый пользователь попадает в массив, который сообщает об этом подписчикам. Datachange - это своего рода поток, который испускает всякий раз, когда данные были изменены. Создайте переменную с именем datachange, которая является объектом поведения, которая имеет массив начальных значений Создайте массив, называемый скопированными данными Создайте нового пользователя с 4 свойствами. Пользователи создаются как объекты здесь, причем эти 4 свойства являются их атрибутами. Вызовите следующий метод с добавленным новым пользователем Вызовите следующий метод по специальному наблюдаемому и subject emits.add user() добавляет пользователя в базу данных, а пользовательский метод строит объект пользователя с 4 различными атрибутами. Источник данных для предоставления данных, которые должны отображаться в таблице. Обратите внимание, что источник данных может каким-либо образом восстановить свои данные. В этом случае источнику данных предоставляется ссылка на общую базу данных ExampleDatabase. Источник данных принимает данные только и передает таблицу точно, что должно быть визуализировано, и ничего больше.

export class ExampleDataSource extends DataSource<any> {
constructor(private _exampleDatabase: ExampleDatabase) {
super();
}
connect(): Observable<UserData[]> {
return this._exampleDatabase.dataChange;
}
 disconnect() {}
 }

Подключение таблицы к источнику данных

Данные передаются в таблицу через DataSource.

Функция Connect соединяет средство просмотра коллекции, такое как таблица данных, с источником данных. Функция Connect вызывается в таблице, чтобы получить поток, содержащий данные, которые должны быть отображены. Параметры этой функции подключения должны быть заданы. Когда таблица получает источник данных, она вызывает функцию подключения DataSources, которая возвращает наблюдаемую, которая испускает массив данных. Всякий раз, когда источник данных испускает данные в этот поток, таблица будет обновляться. Поскольку источник данных предоставляет этот поток, он несет ответственность за запуск обновлений таблиц. Это может быть основано на любом: соединениях веб-сокетов, взаимодействии с пользователем, обновлении модели, временных интервалах и т.д. Чаще всего обновления будут инициироваться пользовательскими взаимодействиями, такими как сортировка и разбивка на страницы. Функция разъединения прерывает соединение между таблицей и источником данных. Давайте посмотрим на файл HTML или наш шаблон. Шаблоны сотовых телефонов

<ng-container cdkColumnDef="color">
     <md-header-cell *cdkHeaderCellDef>Color</md-header-cell>
     <md-cell *cdkCellDef="let row" [style.color]="row.color"> {{row.color}} 
</md-cell>
</ng-container>

Во-первых, столбцы таблицы определены. С директивой cdkColumnDef каждому столбцу присваивается имя. Это имя, из которого этот конкретный столбец в таблице относится к другим местам. Затем в столбце определяется ячейка заголовка шаблон и ячейка cell.header ячейки данных предоставляет и отображает имя столбца, а шаблон ячейки извлекает данные, которые должны отображаться, и отображает их под заголовком в строках. cdkCellDef экспортирует контекст строки строка заголовка таблицы и строка данных определены ниже Шаблоны строк приведены ниже,

 <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
 <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>

'Отображаемый массив столбцов находится в вашем файле .ts(typescript), а цвет - это столбец или элемент массива (в соответствии с нашим примером). Эти шаблоны строк смотрят на имя, присвоенное cdkColumnDef, и обнаруживают конкретные столбцы для рендеринга. CdkRowDef также экспортирует контекст строки. Представленное содержимое строки исходит из шаблонов ячеек не из шаблонов строк. Для дальнейшего ознакомления с этим проверьте это Angular Материал

Изменить описание material.angular.io как динамически генерировать требуемые столбцы?

<ng-container *ngFor="let col of displayedColumns" cdkColumnDef= {{col}}>
<md-header-cell *cdkHeaderCellDef md-sort-header > {{ col }} </md-header-
cell>
 <md-cell  *cdkCellDef="let row"> {{row[col]}} </md-cell>
</ng-container>

сравните этот кусок кода с тем, который был до последнего. Мы прокручиваем массив отображаемых столбцов, а имена столбцов назначаются в процессе, поэтому мы генерируем требуемые столбцы, проходящие через массив, вместо того, чтобы определять все необходимые столбцы вручную в HTML файл. С этим я завершу это объяснение, md tables далее предлагает вам такие функции, как разбиение на страницы, сортировка и фильтрация. Официальная документация включает примеры, на которые вы можете ссылаться, чтобы добавить эти функции в свою таблицу md.

Теперь вы знаете, что происходит за кулисами в таблице md.

Ответ 4

У меня было много проблем, пытающихся использовать этот подход:

import { DataSource } from '@angular/cdk/collections';

....

Я мог бы получить таблицу, но сортировать столбцы было невозможно, потому что сортировка не была известным свойством Datasource и т.д. и т.д.

Наконец, я заметил, что использовал "@ angular/material": "^ 5.0.0-rc0",

В настоящее время я работаю с MatTableDataSource

Импорт

import {MatTableDataSource} from '@angular/material';

ПЕРЕМЕННЫЕ КЛАССЫ

private ELEMENT_DATA: reportInterface[] = [];
public tbDataSource;
public displayedColumns;

и в конструкторе

this.dataService.getReport().subscribe(results => {
if(!results)return;
this.ELEMENT_DATA = results;
this.displayedColumns = [.............];
this.tbDataSource = new MatTableDataSource(this.ELEMENT_DATA);
this.tbDataSource.sort = this.sort;
});

и вот моя функция фильтра

applyFilter(filterValue: string) {
this.tbDataSource.filter = filterValue;
}

Я думаю, что это быстрее и проще