简体   繁体   English

无法在Material Datatable中使用AngularFirestore获取对象键

[英]Can't Fetch Object Keys Using AngularFirestore in Material Datatable

I have a Material Datatable that consists of 3 documents. 我有一个包含3个文档的材料数据表。 In the columns, I have an edit column which needs to fetch the ids ($key) so I can route to /object:id. 在这些列中,我有一个编辑列,该列需要获取id($ key),以便可以路由到/ object:id。

I suspect this is related to async loading but after making a thorough search to the best of my capacity I couldn't really find a solid answer, or admitedly, I don't really know what to search for regarding how to incorporate this into datatable. 我怀疑这与异步加载有关,但是在尽我最大的能力进行了彻底搜索之后,我并没有真正找到可靠的答案, 或者,坦白地说,我真的不知道要寻找什么关于如何将其整合到数据表中的内容。 。

<mat-table #table [dataSource]="vehicle1" [trackBy]="trackByUid" matSort>

When I use the collection (observable) as my datatable source as above, I'm able to fetch the keys and display them, however even-though this displays content, it renders the datatable functions useless such as filtering & sorting. 当我如上所述使用集合(可观察的)作为我的数据表源时,我能够获取键并显示它们,尽管即使显示了内容,它也会使数据表功能无效,例如过滤和排序。

This is my TS & template files: 这是我的TS和模板文件:

(I tried assigning the same value to multiple properties [uid, $key] to make sure it's not a keyword issue) (我尝试为多个属​​性[uid,$ key]分配相同的值,以确保它不是关键字问题)

 import { Component, AfterViewInit, ViewChild } from '@angular/core'; import { MatTableDataSource, MatSort, MatDialog } from '@angular/material'; import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/firestore'; import { StatusDialogComponent } from './status-dialog/status-dialog.component'; import { Vehicle } from '../vehicle'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Component({ moduleId: module.id, selector: 'app-list-vehicles', templateUrl: 'list-vehicles.component.html', styleUrls: ['list-vehicles.component.scss'] }) export class ListVehiclesComponent implements AfterViewInit { vehicleKey: {}; vehicles$: AngularFirestoreCollection<Vehicle>; vehicles: Observable<Vehicle[]>; vehicle: AngularFirestoreDocument; displayedColumns = ['vin', 'make', 'model', 'status', '$key', 'details', 'edit']; dataSource: MatTableDataSource<any>; @ViewChild(MatSort) sort: MatSort; constructor( public afs: AngularFirestore, public dialog: MatDialog, ) { this.vehicles = this.afs.collection(`vehicles`).snapshotChanges().pipe( map(actions => { return actions.map(a => { const data = a.payload.doc.data() as Vehicle; const $key = a.payload.doc.id; console.log('payload: ' + a.payload.doc.id); data.$key = a.payload.doc.id; data.uid = a.payload.doc.id; if (data.$key === null || data.$key === undefined) {console.log('null.'); } else {console.log('full' + data.$key); } return {$key, ...data}; }); }) ); } ngAfterViewInit(): void { this.afs.collection<Vehicle>('vehicles').valueChanges().subscribe(data => { this.dataSource = new MatTableDataSource(data); this.dataSource.sort = this.sort; }); } applyFilter(filterValue: string) { filterValue = filterValue.trim(); filterValue = filterValue.toLowerCase(); this.dataSource.filter = filterValue; } openStatusDialog(data): void { const dialogRef = this.dialog.open(StatusDialogComponent, { width: '400px', data: data, }); } trackByUid(index, item) { return item.uid; } } 
 <div *ngFor="let veh of vehicles | async"> {{veh.$key}} <!-- I can fetch the keys here. --> </div> <div *ngIf="vehicles | async as vehicle1"> <button mat-raised-button color="accent"> A Useless Button </button> <div class="example-header"> <mat-form-field> <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter"> </mat-form-field> </div> <mat-table #table [dataSource]="dataSource" [trackBy]="trackByUid" matSort> <ng-container matColumnDef="vin"> <mat-header-cell *matHeaderCellDef mat-sort-header>VIN</mat-header-cell> <mat-cell *matCellDef="let vehicle"> {{vehicle.vin}} </mat-cell> </ng-container> <ng-container matColumnDef="make"> <mat-header-cell *matHeaderCellDef mat-sort-header>Make</mat-header-cell> <mat-cell *matCellDef="let vehicle"> {{vehicle.make}} </mat-cell> </ng-container> <ng-container matColumnDef="model"> <mat-header-cell *matHeaderCellDef mat-sort-header>Model</mat-header-cell> <mat-cell *matCellDef="let vehicle"> {{vehicle.model}} </mat-cell> </ng-container> <ng-container matColumnDef="status"> <mat-header-cell *matHeaderCellDef mat-sort-header>Status</mat-header-cell> <mat-cell *matCellDef="let vehicle"> {{vehicle.status}} </mat-cell> </ng-container> <ng-container matColumnDef="$key"> <mat-header-cell *matHeaderCellDef mat-sort-header>Key</mat-header-cell> <mat-cell *matCellDef="let vehicle"> {{vehicle.$key}} </mat-cell> </ng-container> <ng-container matColumnDef="details"> <mat-header-cell *matHeaderCellDef mat-sort-header>Details</mat-header-cell> <mat-cell *matCellDef="let vehicle"> <button mat-raised-button color="primary" [routerLink]="['/vehicles', vehicle.$key]"> Details </button> </mat-cell> </ng-container> <ng-container matColumnDef="edit"> <mat-header-cell *matHeaderCellDef mat-sort-header>Edit</mat-header-cell> <mat-cell *matCellDef="let vehicle"> <button mat-raised-button color="warn" (click)="openStatusDialog(vehicle)"> Edit </button> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> <mat-row *matRowDef="let row; columns: displayedColumns;" class="animate"></mat-row> </mat-table> Json: {{(vehicle1 | json)}} <!-- I can also fetch them here. --> </div> 

This is when I'm using the "dataSource" as the data table source: 这是当我使用“ dataSource”作为数据表源时: 在此处输入图片说明

This is when I'm using the observable as the data table source: 这是当我使用observable作为数据表源时: 在此处输入图片说明

Since I'm able to somehow fetch the keys using the observable asynchronous, how do I incorporate a similar method to the data table so I can get the keys using data table? 由于我可以使用可观察的异步方式以某种方式获取密钥,因此如何将类似的方法合并到数据表中,以便可以使用数据表获取密钥? Is there another way of navigating to the documents within a collection using material data tables that I might have missed? 有没有其他方法可以使用我可能会错过的材料数据表导航到集合中的文档?

Subscribing to the observable to build dataSource instead of subscribing to the collection resolved the issue. 订阅可观察的数据源,而不是订阅集合即可解决此问题。

so this: 所以这:

this.afs.collection<Vehicle>('vehicles').valueChanges().subscribe(data => {
        this.dataSource = new MatTableDataSource(data);
        this.dataSource.sort = this.sort;
    });

is replaced with this: 替换为:

this.vehicles.subscribe((d) => this.dataSource = new MatTableDataSource(d));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM