简体   繁体   中英

Angular 4 - Result of Observable to BehaviorSubject

I write table using angular 4 and material design and I want to bind data from service to table. My service is using http to getting data from server and therfore returns Promise or Observable. How can I assign result of Observable or Promise method to variable dataChange of type BehaviorSubject<> ?

import { Component, OnInit, ElementRef, ViewEncapsulation, ViewChild } from '@angular/core';
import { DataSource } from '@angular/cdk';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { MdPaginator, MdSort } from '@angular/material';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
declare let d3: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})


export class AppComponent implements OnInit {

  displayedColumns = ['shiftDate', 'swipeIn', 'swipeOut', 'duration', 'status'];
  exampleDatabase = new ExampleDatabase();
  dataSource: ExampleDataSource | null;

  @ViewChild(MdPaginator) paginator: MdPaginator;
  @ViewChild(MdSort) sort: MdSort;

  ngOnInit() {
    this.dataSource = new ExampleDataSource(this.exampleDatabase, this.paginator, this.sort);
  }
}

export interface attendanceData {
  shiftDate: string;
  swipeIn: string;
  swipeOut: string;
  duration: string;
  status: string;
}


/** An example database that the data source uses to retrieve data for the table. */
export class ExampleDatabase {
  /** Stream that emits whenever the data has been modified. */
  dataChange: BehaviorSubject<attendanceData[]> = new BehaviorSubject<attendanceData[]>([]);
  get data(): attendanceData[] {

    let data = [
      {
        "shiftDate": "17-July-2017",
        "swipeIn": "10:00 AM",
        "swipeOut": "06:00 PM",
        "duration": "8 Hours",
        "status": "PRESENT"

      },
      {
        "shiftDate": "16-July-2017",
        "swipeIn": "9:00 AM",
        "swipeOut": "5:00 AM",
        "duration": "7 Hours",
        "status": "PRESENT"
      }

    ];

    return data;
  }

  constructor() {

    this.dataChange.next(this.data);
  }

}

export class ExampleDataSource extends DataSource<any> {
  _filterChange = new BehaviorSubject('');
  get filter(): string { return this._filterChange.value; }
  set filter(filter: string) { this._filterChange.next(filter); }

  constructor(private _exampleDatabase: ExampleDatabase, private _paginator: MdPaginator, private _sort: MdSort) {
    super();
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<attendanceData[]> {
    const displayDataChanges = [
      this._exampleDatabase.dataChange,
      this._paginator.page,
      this._sort.mdSortChange
    ];

    return Observable.merge(...displayDataChanges).map(() => {
      // const data = this._exampleDatabase.data.slice();
      const data = this.getSortedData();
      // Grab the page's slice of data.
      const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
      return data.splice(startIndex, this._paginator.pageSize);
    });
  }

  disconnect() { }

  getSortedData(): attendanceData[] {
    const data = this._exampleDatabase.data.slice();
    if (!this._sort.active || this._sort.direction == '') { return data; }

    return data.sort((a, b) => {
      let propertyA: number | string = '';
      let propertyB: number | string = '';

      switch (this._sort.active) {
        case 'shiftDate': [propertyA, propertyB] = [a.shiftDate, b.shiftDate]; break;
        case 'swipeIn': [propertyA, propertyB] = [a.swipeIn, b.swipeIn]; break;
        case 'swipeOut': [propertyA, propertyB] = [a.swipeOut, b.swipeOut]; break;
        case 'duration': [propertyA, propertyB] = [a.duration, b.duration]; break;
      }

      let valueA = isNaN(+propertyA) ? propertyA : +propertyA;
      let valueB = isNaN(+propertyB) ? propertyB : +propertyB;

      return (valueA < valueB ? -1 : 1) * (this._sort.direction == 'asc' ? 1 : -1);
    });
  }
}

Subject can act as an observer so you can simply subscribe it to the observable:

dataChange: BehaviorSubject<attendanceData[]> = new BehaviorSubject<attendanceData[]>([]);

observable.subscribe(this.dataChange)

You don't need to call next on the subject the way you do it:

this.myService.getObjects().subscribe(res => this.dataChange.next(res))

It will be called automatically. It's enough to just subscribe the subject as I showed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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