目前我有这个设置.我的代码工作得很好,没有带有标准Angular设置和代码的表,使用ngFor并从模板创建列表.所以代码使用AngularFire 2从Firebase传递数据.尝试新的md数据表就是问题所在.
首先,模板不会渲染.我知道我已经正确设置了NgModule,所以我怀疑数据源没有连接并且创建了这个错误.这是Chrome控制台中的错误.
Template parse errors: Can't bind to 'dataSource' since it isn't a kNown property of 'md-table'. 1. If 'md-table' is an Angular component and it has 'dataSource' input,then verify that it is part of this module.
我的members- search.component.html看起来与官方文档相同,只是我更改了模板绑定:
<md-table #table [dataSource]="dataSource">
<ng-container cdkColumnDef="memberName">
<md-header-cell *cdkHeaderCellDef> Name </md-header-cell>
<md-cell *cdkCellDef="let row"> {{member.firstName}} {{ member?.lastName }} </md-cell>
</ng-container>
members-search.component.ts包含以下相关部分:
import { DataSource } from '@angular/cdk';
@Injectable()
export class MembersAdminService {
private members$: FirebaseListObservable<Member[]>;
private dataSource: DataSource<any>;
constructor(
private af: AngularFireDatabase,@Inject(FirebaseApp) fb) {
this.members$= af.list('Members');
}
我将这些数据表函数放入members-search.service.ts中的工作代码中,并在connect()中使用了与我在其他地方使用的相同代码.
// md table dataSource functions.
public connect(): FirebaseListObservable<any> {
return this.af.list('Members',{
query: {
orderByChild: 'lastName'
}
});
// return this._exampleDatabase.dataChange;
}
public disconnect() {}
数据表docs和plunker在组件中创建了一个数据源和数据库,但是如果我已经拥有Firebase,那么大多数情况似乎都没有必要.我正在学习所有这些,所以我在任何事情上都不是专家,也许我错过了一些东西.
如果您之前没有进入这个新设置,那么这里是文档. md表构建在cdk表的顶部,为cdk表提供样式.
https://material.angular.io/components/table/overview
https://material.angular.io/guide/cdk-table
成员admin.service.ts
import { AngularFireDatabase,FirebaseListObservable } from 'angularfire2/database';
import { FirebaseApp } from 'angularfire2';
import { Inject,Injectable } from '@angular/core';
import { MemberModel } from './member-admin.model';
import { SuccessService } from '../../../shared/success.service';
// Data Table imports.
import { MdPaginator } from '@angular/material';
import { DataSource } from '@angular/cdk';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/observable/combineLatest';
import 'rxjs/add/operator/map';
@Injectable()
export class MembersAdminService {
private membersData$: FirebaseListObservable<MemberModel[]>;
constructor(
public af: AngularFireDatabase,private successService: SuccessService,// For Create and Update functions.
@Inject(FirebaseApp) fb) {
this.membersData$= af.list('Members');
}
// ... CRUD stuff not relevant to the MD Table ...
// *** MD DATA TABLE SERVICES. ***
@Injectable()
export class MemberDatabase {
/* Stream that emits whenever the data has been modified. */
public dataChange: BehaviorSubject<MemberModel[]> = new BehaviorSubject<MemberModel[]>([]);
get data(): MemberModel[] {
return this.dataChange.value; }
// Connection to remote db.
private database = this.memberAdminService.af.list('Members',{
query: {
orderByChild: 'lastName'
}
});
public getMembers(): FirebaseListObservable<MemberModel[]> {
return this.database;
}
constructor(private memberAdminService: MembersAdminService) {
this.getMembers()
.subscribe(data => this.dataChange.next(data));
}
}
@Injectable()
export class MembersAdminSource extends DataSource<MemberModel> {
constructor(
private memberDatabase: MemberDatabase,private paginator: MdPaginator) {
super();
}
/** Connect function called by the table to retrieve one stream containing the data to render. */
connect(): Observable<MemberModel[]> {
const displayDataChanges = [
this.memberDatabase.dataChange,this.paginator.page,];
return Observable
.merge(...displayDataChanges) // Convert object to array with spread Syntax.
.map(() => {
const dataSlice = this.memberDatabase.data.slice(); // Data removed from viewed page.
// Get the page's slice per pageSize setting.
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
const dataLength = this.paginator.length; // This is for the counter on the DOM.
return dataSlice.splice(startIndex,this.paginator.pageSize);
});
}
disconnect() {}
}
全members.component.ts
在ngOnInit和类属性中进行了一些重构.
import { Component,OnInit,ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { Subject } from 'rxjs/Subject';
// For MD Data Table.
import { MdPaginator } from '@angular/material';
import { MembersAdminService,MembersAdminSource,MemberDatabase } from './member-admin.service';
import { ConfirmService } from '../../../shared/confirm.service';
import { MemberModel } from './member-admin.model';
@Component({
selector: 'app-all-members',templateUrl: './all-members.component.html'
})
export class AllMembersComponent implements OnInit {
membersData: MemberModel[];
private result: boolean;
allMembers: MemberModel[];
// For search
startAt = new Subject();
endAt = new Subject();
lastKeypress: 0;
// For MD data table.
// private memberDatabase = new MemberDatabase(); // Requires a param but? Moved to constructor.
private dataSource: MembersAdminSource | null;
private displayedColumns = [
'firstName','lastName','mainSkillTitle','mainSkills','delete','key'
];
@ViewChild(MdPaginator)
paginator: MdPaginator;
public dataLength: any; // For member counter on DOM.
constructor(
private membersAdminService: MembersAdminService,private memberDatabase: MemberDatabase,private router: Router,private confirmService: ConfirmService
) {}
ngOnInit() {
this.memberDatabase.getMembers()
.subscribe(members => {
this.dataSource = new MembersAdminSource(this.memberDatabase,this.paginator);
this.dataLength = members;
});
}
全members.component.html
注意我在行中有按钮用于删除和编辑,它们工作正常.诀窍是您需要隐藏列中的数据库密钥.
<md-table #table [dataSource]="dataSource">
<!-- First Name Column -->
<ng-container cdkColumnDef="firstName">
<md-header-cell *cdkHeaderCellDef> First Name </md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.firstName}} </md-cell>
</ng-container>
<!-- Las Name Column -->
<ng-container cdkColumnDef="lastName">
<md-header-cell *cdkHeaderCellDef> Last Name </md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.lastName}} </md-cell>
</ng-container>
<!-- Title Column -->
<ng-container cdkColumnDef="mainSkillTitle">
<md-header-cell *cdkHeaderCellDef> Title </md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.mainSkillTitle}} </md-cell>
</ng-container>
<!-- Main Skills Column -->
<ng-container cdkColumnDef="mainSkills">
<md-header-cell *cdkHeaderCellDef> Main Skills </md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.mainSkills}} </md-cell>
</ng-container>
<!-- Delete Buttons Column -->
<ng-container cdkColumnDef="delete">
<md-header-cell *cdkHeaderCellDef> Delete / Edit </md-header-cell>
<md-cell *cdkCellDef="let row">
<button (click)="deleteMember(row.$key)">Delete</button>
<button (click)="goToDetailPage(row.$key)">Edit</button>
</md-cell>
</ng-container>
<!-- Database key Column -->
<ng-container cdkColumnDef="key">
<md-header-cell *cdkHeaderCellDef class="hiddenField"> Key </md-header-cell>
<md-cell *cdkCellDef="let row" class="hiddenField"> {{row.$key}} </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]="dataLength?.length"
[pageIndex]="0"
[pageSize]="5"
[pageSizeOptions]="[5,10,25,100]">
</md-paginator>