角度 - 使用JSON填充材料表

时间:2017-10-17 21:03:06

标签: json angular angular-material

我试图建立我的第一个网站,我需要一些非常简单的东西,包括CRUD操作。我一般都是Angular和JS的绝对初学者,但在看完一些教程后,我设法解决了一些问题。现在我在尝试使用JSON数据填充材质表时陷入困境。如果我手动设置它的数据(下面的代码),但我无法弄清楚如何使用JSON。由于我需要过滤,排序和分页作为模板,因此我使用了富表"富表"演示示例和this question.

中的一些代码

我认为你不需要html部分,但如果你这样做,我可以更新:

import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {DataSource} from '@angular/cdk/collections';
import {Http, Response, RequestOptions, Headers, Request, RequestMethod} from '@angular/http';
import {MatPaginator, MatSort} from '@angular/material';
import {SelectionModel} from '@angular/cdk/collections';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/operator/switchMap';

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

export class PregledComponent implements OnInit {
  displayedColumns = ['userId', 'userName', 'progress', 'color'];
  exampleDatabase: ExampleDatabase | null;
  selection = new SelectionModel<string>(true, []);
  dataSource: ExampleDataSource | null;


  constructor(private http: Http) {
  }

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  @ViewChild('filter') filter: ElementRef;

  ngOnInit() {
    this.loadData();
  }

  loadData() {
    this.exampleDatabase = new ExampleDatabase(this.http);
    this.dataSource = new ExampleDataSource(this.exampleDatabase, this.paginator, this.sort);
    Observable.fromEvent(this.filter.nativeElement, 'keyup')
      .debounceTime(150)
      .distinctUntilChanged()
      .subscribe(() => {
        if (!this.dataSource) {
          return;
        }
        this.dataSource.filter = this.filter.nativeElement.value;
      });
  }

  isAllSelected(): boolean {
    if (!this.dataSource) { return false; }
    if (this.selection.isEmpty()) { return false; }

    if (this.filter.nativeElement.value) {
      return this.selection.selected.length === this.dataSource.renderedData.length;
    } else {
      return this.selection.selected.length === this.exampleDatabase.data.length;
    }
  }

  masterToggle() {
    if (!this.dataSource) { return; }

    if (this.isAllSelected()) {
      this.selection.clear();
    } else if (this.filter.nativeElement.value) {
      this.dataSource.renderedData.forEach(data => this.selection.select(data.id));
    } else {
      this.exampleDatabase.data.forEach(data => this.selection.select(data.id));
    }
  }
}

export interface UserData {
  id: string;
  location: string;
  title: string;
  color: 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<UserData[]> = new BehaviorSubject<UserData[]>([]);

  private issuesUrl = 'https://mydemourl...com/angular/getdata.php';  // URL to web API
  getRepoIssues(): Observable<UserData[]> {
    return this.http.get(this.issuesUrl)
      .map(this.extractData);
  }

  extractData(result: Response): UserData[] {
    return result.json().map(issue => {
      return {
        id: issue.id,
        location: issue.location,
        title: issue.title,
        color: issue.color,
      };
    });
  }


/*THIS IS A ISSUE HERE
My best guess was:

get data(): UserData [] {return.this.getRepoIssues}

but I get error with observables...

*/

  get data(): UserData [] {
    const data = [
      {
        "id": "17-July-2017",
        "location": "10:00 AM",
        "title": "06:00 PM",
        "color": "8 Hours",
      },
      {
        "id": "17-July1-2017",
        "location": "10:00 AM",
        "title": "06:00 PM",
        "color": "8 Hours",
      },
      {
        "id": "test",
        "location": "123",
        "title": "06:00 PM",
        "color": "bluee",
      }]

    return data;
  }

  constructor(private http: Http) {

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

}

/**

/** An example database that the data source uses to retrieve data for the table.
export class ExampleDatabase {

  dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]);
  // get data(): UserData[] { return this.dataChange.value; }
  get data(): UserData[]{
    let data = [this.getRepoIssues()];
    return this.dataChange.value;
  }
  private issuesUrl = 'https://antonio1991.000webhostapp.com/angular/getdata.php';  // URL to web API

  getRepoIssues(): Observable<UserData[]> {
    return this.http.get(this.issuesUrl)
      .map(this.extractData);
  }

  extractData(result: Response): UserData[] {
    return result.json().map(issue => {
      return {
        id: issue.id,
        location: issue.location,
        title: issue.title,
        color: issue.color,
      };
    });
  }

  constructor(private http: Http) {}

}
*/



/**
 * Data source to provide what data should be rendered in the table. Note that the data source
 * can retrieve its data in any way. In this case, the data source is provided a reference
 * to a common data base, ExampleDatabase. It is not the data source's responsibility to manage
 * the underlying data. Instead, it only needs to take the data and send the table exactly what
 * should be rendered.
 */
export class ExampleDataSource extends DataSource<UserData> {
  _filterChange = new BehaviorSubject('');
  get filter(): string { return this._filterChange.value; }
  set filter(filter: string) { this._filterChange.next(filter); }

  filteredData: UserData[] = [];
  renderedData: UserData[] = [];

  constructor(private _exampleDatabase: ExampleDatabase,
              private _paginator: MatPaginator,
              private _sort: MatSort) {
    super();
    // Reset to the first page when the user changes the filter.
    this._filterChange.subscribe(() => this._paginator.pageIndex = 0);
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<UserData[]> {
    // Listen for any changes in the base data, sorting, filtering, or pagination
    const displayDataChanges = [
      this._sort.sortChange,
      this._filterChange,
      this._paginator.page,
    ];

    return Observable.merge(...displayDataChanges).map(() => {
      // Filter data
      this.filteredData = this._exampleDatabase.data.slice().filter((item: UserData) => {
        const searchStr = (item.id + item.location).toLowerCase();
        return searchStr.indexOf(this.filter.toLowerCase()) !== -1;
      });

      // Sort filtered data
      const sortedData = this.sortData(this.filteredData.slice());

      // Grab the page's slice of the filtered sorted data.
      const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
      this.renderedData = sortedData.splice(startIndex, this._paginator.pageSize);
      return this.renderedData;
    });
  }

  disconnect() {}

  /** Returns a sorted copy of the database data. */
  sortData(data: UserData[]): UserData[] {
    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 'userId': [propertyA, propertyB] = [a.id, b.id]; break;
        case 'userName': [propertyA, propertyB] = [a.location, b.location]; break;
        case 'progress': [propertyA, propertyB] = [a.title, b.title]; break;
        case 'color': [propertyA, propertyB] = [a.color, b.color]; break;
      }

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

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

1 个答案:

答案 0 :(得分:2)

角度材料文档还有很多不足之处。有一些链接帮我把这样的东西放在一起:

问题是你试图在数据的getter方法中使用HTTP get,这应该返回UserData列表而不是http响应。此外,您只需要调用一次请求,而不是每次观察者都连接到数据源时。

如果要在组件的init上执行ajax调用,可以将其放在DataSource的connect()方法中。

将ExampleDatabase dataChange Observable添加到displayDataChanges列表,并在DataSource的连接器中调用http GET:

connect(): Observable<UserData[]> {
    // Listen for any changes in the base data, sorting, filtering, or pagination
    const displayDataChanges = [
      this._exampleDatabase.dataChange,
      this._sort.sortChange,
      this._filterChange,
      this._paginator.page,
    ];

    this._exampleDatabase. getRepoIssues()

在exampleDatabase中,getRepoIssues执行HTTP调用并在Observable dataChange中设置数据,而getter data返回Observable的值:

export class ExampleDatabase {
  /** Stream that emits whenever the data has been modified. */
  dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]);

  get data(): UserData[]{
    return this.dataChange.value;
  }

  private issuesUrl = 'https://mydemourl...com/angular/getdata.php';  // URL to web API
  getRepoIssues(): void {
    const myData = this.http.get(this.issuesUrl)
                   .map(this.extractData);

    myData.subscribe(
        result => {
            this.dataChange.next(result);
        },
    );
  }

  extractData(result: Response): UserData[] {
    return result.json().map(issue => {
      return {
        id: issue.id,
        location: issue.location,
        title: issue.title,
        color: issue.color,
      };
    });
  }