我希望它只是即插即用:-)我一直在喋喋不休地打了几个小时没有我的小实验工作. md数据表是新的,因此Web上几乎没有神圣的知识.找到将Firebase连接到桌面的好方法将是一个良好的开端.有任何想法吗?
目前我有这个设置.我的代码工作得很好,没有带有标准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表提供样式.
我在为MD数据表使用MD Paginator时添加了连接到Firebase的代码. Paginator使服务中的代码更加复杂.大多数代码都在它所属的服务中.请享用!
成员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>