Элемент управления Angular 7 со списком с динамическими данными c - PullRequest
0 голосов
/ 16 марта 2020

У меня есть приложение angular 8, и я использую материал angular с вкладками.

И у меня есть четыре вкладки

Но каждая вкладка имеет свои собственные элементы (данные). Но сначала я проверяю, правильно ли загружены данные на одной вкладке. Но теперь я вижу все данные (поэтому объединены четыре вкладки) на вкладке. А не отфильтрованные данные для указанной вкладки c.

Так вот как выглядит шаблон:



    <mat-tab-group
      (selectedTabChange)="onTabChange($event)"
      [selectedIndex]="selectedTab"
      (selectedIndexChange)="setTabState($event)"
    >
      <mat-tab [label]="tab.name" *ngFor= "let tab of tabs" >
        <div class="mat-elevation-z8 table-container">
          <table *ngIf = "tab.dataSource && tab.dataSource.data"  mat-table [dataSource]="tab.dataSource" matSort aria-label="Elements">

            <ng-container matColumnDef="title">
              <th mat-header-cell *matHeaderCellDef mat-sort-header i18n>Title</th>
              <td mat-cell *matCellDef="let row">{{ row.title }}</td>
            </ng-container>

            <ng-container matColumnDef="createdAt">
              <th mat-header-cell *matHeaderCellDef mat-sort-header i18n>Date</th>
              <td mat-cell *matCellDef="let row">{{ row.createdAt | date: 'shortDate' }}</td>
            </ng-container>

            <ng-container matColumnDef="view">
              <th mat-header-cell *matHeaderCellDef i18n>View</th>
              <td mat-cell *matCellDef="let row">
                <a mat-button mat-icon-button [routerLink]="['..', row.id]"><mat-icon>visibility</mat-icon></a>
              </td>
            </ng-container>

            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
            <tr mat-row [routerLink]="['..', row.id]" *matRowDef="let row; columns: displayedColumns"></tr>
          </table>

        </div>


           <ng-template mat-tab-label>
            <mat-icon class="interviews">speaker_notes</mat-icon>
            <span i18n>Interview reportssss</span>{{ dossierItemsCountString(itemTypes.Interview) }}
            <a [routerLink]="['../', dossier.id, 'item', 'new', itemTypes.Interview]"
              ><mat-icon class="add_box">add</mat-icon>
            </a>
          </ng-template>
          <ng-container *ngTemplateOutlet="itemList; context: { itemType: itemTypes.Note }"></ng-container>

      </mat-tab>
    </mat-tab-group>
<ng-template #itemList let-itemType="itemType">
</ng-template>

<div>
  <a routerLink=".." mat-button i18n>Back</a>
</div>
<ng-template #itemView let-item="item"> </ng-template>


, а это файл ts:


export class ViewComponent implements OnInit, AfterViewInit {
  dossier: DossierDto;
  dossierItems: DossierItemDto[] = [];
  itemSearchMatches = {};
  typeSearchMatches = {};
  formBuilder = new FormBuilder();
  editDossierForm: FormGroup;
  globalEditDossierErrors: ValidationErrors;
  itemTypes = DossierItemTypeDto;
  searchQueryHolder = '';
  @ViewChild('tabGroup') tabGroup;
  selectedTabIndex: number;
  selectedTab = 0;
  datasource: MatTableDataSource<DossierDto>;
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;


  activeTab;
  tabs = [
    { name: 'Tab 1', dataSource: new MatTableDataSource<DossierDto>([]) },
  ];

  constructor(
    private dossierService: DossierService,
    private uiStateService: UIStateService,
    route: ActivatedRoute,
    private errorProcessor: ErrorProcessor
  ) {

    this.dossier = route.snapshot.data.dossier;
    this.dossierItems = route.snapshot.data.dossierItems;
    this.searchDossieritems(null);
    this.editDossierForm = this.formBuilder.group({
      name: this.formBuilder.control(this.dossier.name, [Validators.required])
    });
    this.editDossierForm.disable();
  }

  public readonly displayedColumns = [
    'title',
    'createdAt',
    'view'
  ];

  @ViewChildren(MatSort) matSorts: QueryList<MatSort>;

  ngAfterViewInit(): void {
    // this.datasource.paginator = this.paginator;
    // this.datasource.sort = this.sort;
  }

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


  ngOnInit(): void {

    this.activeTab = this.tabs[0];
    this.loadData().subscribe((data) => {
      this.activeTab.dataSource = new MatTableDataSource(data);
      this.activeTab.dataSource.sort = this.matSorts.toArray()[0];
    });

    const state = this.uiStateService.getState();
    if (state) {
      this.selectedTab = state.tabState || 0; // If there is no state
    }
    this.setTabState(state.tabState);
  }


  set searchQuery(value: string) {
    this.searchQueryHolder = value;
  }

  onTabChange(event ) {
    this.activeTab = this.tabs[event.index];
    this.loadData().subscribe((data) => {
      this.activeTab.dataSource = new MatTableDataSource(data);
      this.activeTab.dataSource.sort = this.matSorts.toArray()[event.index];
    });
  }

  loadData(): Observable<DossierDto[]> {
    // To simulate async request
    return of(this.dossierItems).pipe(delay(1000));
  }



  dossierItemsCountString(itemType: DossierItemTypeDto) {
    const count = this.dossierItemsCountBy(itemType);

    if (this.hasSearchQuery) {
      return `(${count.matches}/${count.total})`;
    } else {
      return `(${count.total})`;
    }
  }
}

, и это метод загрузки данных для каждой указанной вкладки c:

dossierItemsBy(itemType: DossierItemTypeDto) {
    return this.dossierItems.filter(
      i => i.itemType === itemType && (!this.hasSearchQuery || this.itemSearchMatches[i.id].hasMatch)
    );
  }

, а DossierTypeDto выглядит следующим образом:

export type DossierItemTypeDto = 'Interview' | 'Note' | 'Goal' | 'ActionStep';

export const DossierItemTypeDto = {
  Interview: 'Interview' as DossierItemTypeDto,
  Note: 'Note' as DossierItemTypeDto,
  Goal: 'Goal' as DossierItemTypeDto,
  ActionStep: 'ActionStep' as DossierItemTypeDto
};

Итак, четыре вкладки : interivew, примечание, цель и ActionStep.

и для каждой вкладки вы можете добавлять предметы. Так что не для каждой вкладки у вас одни и те же данные. Но это динамически c.

Я нашел пример стекаблика: https://stackblitz.com/edit/am-all-imports-2pxhos?file=app%2Fapp.component.ts

Но там данные для каждой вкладки одинаковы.

Но вот мой вопрос: как сделать это динамически?

Спасибо

, если я отлаживаю в этой строке:

 const count = this.dossierItemsCountBy(itemType);

Я вижу правильный itemType: , но счет всегда 0

1 Ответ

1 голос
/ 17 марта 2020

Посмотрите Angular Документы по материалам для Вкладки и различные примеры .

Например:

<mat-tab-group [selectedIndex]="selected.value"
               (selectedIndexChange)="selected.setValue($event)">
  <mat-tab *ngFor="let tab of tabs; let index = index" [label]="tab">
    Contents for {{tab}} tab
  </mat-tab>
</mat-tab-group>

Stackblitz для динамического c контента.

В качестве источника данных вы должны использовать tab.dataSource для своей таблицы.

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