簡體   English   中英

Angular-用JSON填充材料表

[英]Angular - Populating Material Table with JSON

我正在嘗試建立我的第一個網站,並且我需要一個非常簡單的帶有CRUD操作的表格。 一般來說,我絕對是Angular和JS的初學者,但是看了幾節教程后,我設法解決了一些問題。 現在,我在嘗試用JSON數據填充材料表時遇到了麻煩。 如果我手動設置數據,它可以工作(下面的代碼),但是我不知道如何使用JSON。 由於我需要過濾器,排序和分頁作為模板,因此我使用了“豐富表”演示示例以及該問題的一些代碼

我認為您不需要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);
    });
  }
}

角材文檔尚有許多不足之處。 有一些鏈接可以幫助我將類似的內容組合在一起:

問題是您正在嘗試在數據的getter方法中進行HTTP獲取,該方法應返回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()

在您的getRepoIssues中, 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,
      };
    });
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM