我试图建立我的第一个网站,我需要一些非常简单的东西,包括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);
});
}
}
答案 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,
};
});
}