Angular Material 2数据表是否连接到AngularFire2或Firebase服务? [英] Angular Material 2 Data Table Connect to AngularFire2 or Firebase Service?

查看:59
本文介绍了Angular Material 2数据表是否连接到AngularFire2或Firebase服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望它只是即插即用:-)我已经在这个问题上苦苦挣扎了好几个小时,而我的小实验都没有. md数据表是新的,因此在Web上几乎还没有神学的知识.找到将Firebase连接到表的好方法将是一个好的开始.有什么想法吗?

I wish it was just plug and play :-) I've been thrashing around with this for hours with none of my little experiments working. The md data table is new, so there is almost no divine knowledge on the Web yet. Finding a good way to connect Firebase to the table would be a good start. Any ideas?

当前,我有此设置.如果没有带有标准Angular设置和代码的表,使用ngFor并从模板创建列表,我的代码就可以很好地工作.因此,代码使用AngularFire 2从Firebase传递了数据.尝试新的md数据表是问题所在.

Currently I have this setup. My code works great without the table with the standard Angular setup and code, using ngFor and creating a list from a template. So the code delivers the data from Firebase with AngularFire 2. Trying out the new md data table is the problem.

首先,模板不会呈现.我知道我的NgModule设置正确,所以我怀疑数据源没有连接并产生此错误.这是Chrome控制台中的错误.

First, the template won't render. I know I have NgModule setup correctly so my suspicion is that the data source isn't connecting and creating this error. This is the error in the Chrome console.

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看起来与官方文档相同:

My members-search.component.html looks identical to the official docs except I changed the template binding:

<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具有以下相关部分:

members-search.component.ts has these relevant parts:

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()中使用了与该服务其他地方相同的代码.

And I dropped these data table functions into my working code in members-search.service.ts and used the same code in the connect() that I've been using elsewhere on this service.

// 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,那么似乎大多数不必要.我正在学习所有这些内容,因此我在任何事情上都远非专家,也许我错过了一些东西.

The data table docs and plunker create a data source and database in the component but it seems that most of that isn't necessary if I already have Firebase. I'm learning all this so I'm far from an expert at anything and maybe I'm missing something.

如果您之前还没有进入这个新设置,那么这里是文档. md表建立在cdk表的顶部,以使cdk表具有样式.

If you haven't got into this new setup before then here are the docs. The md table is built on top of the cdk table to give the cdk table the styling.

https://material.angular.io/components/table/overview

https://material.angular.io/guide/cdk-table

推荐答案

我添加了将MD Paginator用于MD数据表时连接到Firebase的代码.分页器使服务中的代码更加复杂.大多数代码在它所属的服务中.享受吧!

I've added the code for connecting to Firebase when using the MD Paginator for the MD Data Table. The Paginator makes the code in the service more complicated. Most of the code is in the service where it belongs. Enjoy!

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() {}
}

all-members.component.ts

ngOnInit和类属性中进行了一些重构.

all-members.component.ts

Did some refactoring in ngOnInit and the class properties.

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;
          });
    }

all-members.component.html

注意,我在行中有用于删除和编辑的按钮,它们可以正常工作.诀窍是您需要在隐藏列中使用数据库密钥.

all-members.component.html

Notice I have buttons in the rows for delete and edit and they work fine. The trick is you need the database key in a hidden column.

<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>

这篇关于Angular Material 2数据表是否连接到AngularFire2或Firebase服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆