У меня есть приложение 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