md-table DataSource с FirebaseListObservable

У меня есть FirebaseListObservable и BehaviorSubject, прослушивающие входной фильтр.

Теперь я хочу объединить обоих парней и вернуть массив, отфильтрованный со значением из ввода, чтобы передать md-таблицу.

Я получил пример из https://material.angular.io/components/table/examples таблица фильтрации.

Может кто-нибудь помочь мне? Спасибо.

Изменить:

Теперь это работает, но я получаю сообщение об ошибке при загрузке компонента. После того, как я пишу что-то в поле ввода, начинает нормально работать.

ОШИБКА TypeError: вы предоставили «неопределенное» там, где ожидался поток. Вы можете предоставить Observable, Promise, Array или Iterable.

Что я делаю не так?

export class DataSourcePessoas extends DataSource<any> {

  pessoas: FirebaseListObservable<any[]>;

  _filterChange = new BehaviorSubject('');
  get filter(): string { return this._filterChange.value; }
  set filter(filter: string) { this._filterChange.next(filter); }

  dados: any[] = [];

  constructor(private pessoasService: FirebasePessoasService) {
    super();
  }

  connect(): Observable<any> {
    const displayDataChanges = [
      this.pessoas,
      this._filterChange,
    ];

    this.pessoas = this.pessoasService.BuscarPessoas();

    this.pessoas.subscribe(items => {console.log(items); this.dados = items});

    return Observable.merge(...displayDataChanges).map(() => {
      return this.dados.filter(valor => {
        return valor.nome.toLowerCase().indexOf(this.filter.toLowerCase()) !== -1})});

  }

  disconnect() {}
}

person Taison Morris    schedule 27.07.2017    source источник


Ответы (2)


Что ж, я хочу сообщить вам одну вещь: если вы обновите что-либо в своем firebaseListObservable, оно автоматически обновит вашу базу данных firebase, поэтому, если вы собираетесь обновить свой firebaseListObservable только для того, чтобы отразить его в вашем представлении, а не в вашей базе данных, тогда не делайте этого. сделай это. Не обновляйте свой firebaseListObservable до тех пор, пока вы не захотите также отразить изменения в своей базе данных firebase. Надеюсь поможет спасибо

//reference Code
$tasks: FirebaseListObservable<Task[]>;
tasks:any[];

$tasks = this.db.list('/users/' + uid);

$tasks.subscribe((todoitems) => {
            console.log('items', todoitems);
            this.tasks = todoitems;
        });
//Now you can easily apply filter on this.tasks.filter(()=>{return});
person Usman Hussain    schedule 27.07.2017
comment
Спасибо за совет. Как вы предлагаете получить список из firebase и использовать this.filter для фильтрации значений и отображения в моей таблице? - person Taison Morris; 27.07.2017
comment
@TaisonMorris Я добавил простой пример кода, надеюсь, он поможет. - person Usman Hussain; 27.07.2017
comment
Немного помогло, спасибо! Но я получаю эту ошибку при загрузке компонента. После того, как я ввожу что-то во ввод, начинает работать... ОШИБКА TypeError: Вы предоставили «неопределенное» там, где ожидался поток. Вы можете предоставить Observable, Promise, Array или Iterable. - person Taison Morris; 27.07.2017
comment
Это означает, что когда компонент загружен, ваш массив пуст, возможно, это проблема. попробуйте инициализировать его пустым массивом или используйте оператор безопасной навигации в привязке шаблона. Откройте эту ссылку и перейдите к ответу с зеленой галочкой, он подробно изложил проблему, и это та же проблема, что и у вас. stackoverflow.com/questions/42364184/ - person Usman Hussain; 28.07.2017

Я решил свою проблему, изменив BehaviorSubject на Observable

import {Component, ElementRef, ViewChild, OnInit} from '@angular/core';
import {DataSource} from '@angular/cdk';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/observable/fromEvent';

import { FirebaseListObservable } from 'angularfire2/database';
import { FirebasePessoasService } from './../../firebase/firebase-pessoas.service';


@Component({
  selector: 'app-pessoas',
  templateUrl: './pessoas.component.html',
  styleUrls: ['./pessoas.component.scss']
})
export class PessoasComponent implements OnInit {
  displayedColumns = ['nome', 'nascimento', 'email', 'telefone'];
  dataSource: DataSourcePessoas | null;

  @ViewChild('filter') filter: ElementRef;

  constructor(private pessoasService: FirebasePessoasService) {
  }

  ngOnInit() {
    this.dataSource = new DataSourcePessoas(this.pessoasService);
    this.dataSource.input = Observable.fromEvent(this.filter.nativeElement, 'keyup');

  }

  public rowClick(row) {
    console.log(row); // row click
  }
}

export class DataSourcePessoas extends DataSource<any> {

  pessoas: FirebaseListObservable<any[]>;

  input: Observable<any>;

  dados: any[] = [];

  ultimoValor: string = '';

  constructor(private pessoasService: FirebasePessoasService) {
    super();
  }

  connect(): Observable<any> {
    this.pessoas = this.pessoasService.BuscarPessoas();

    this.pessoas.subscribe(items => {this.dados = items});

    const aaa = this.pessoas.merge(this.input);
    return aaa.map(x => {
      if (x.constructor.name === 'Array' ) {
        return x.filter(valor => {
          return valor.nome.toLowerCase().indexOf(this.ultimoValor.toLowerCase()) !== -1})
      } else {
        this.ultimoValor = x.target.value;
        return this.dados.filter(valor => {
          return valor.nome.toLowerCase().indexOf(x.target.value.toLowerCase()) !== -1});
      }});
  }

  disconnect() {}
}
person Taison Morris    schedule 30.07.2017