Man*_*ppa 14 javascript datatable json nested angular
需要有关嵌套数据的Angular数据表的帮助.
我想对表中的数据进行排序.
我使用的数据表来自 - https://www.npmjs.com/package/angular2-datatable
数据表适用于单个数组类型的数据.(用于许多角度应用)
问题:我已经嵌套了json(实际上,我有复杂的json,这里很简单)
感谢您查看这个.
任何建议或帮助表示赞赏.
JSON
records = [
[
{
"name": "Subject Name",
"type": "text",
"id": "subjectName",
"value": "DavidJ",
"firstName": "David",
"lastName": "John"
},
{
"name": "QC Name",
"type": "hidden",
"id": "qcName",
"value": "JosephT",
"firstName": "Joseph",
"lastName": "Tom"
}
],
[
{
"name": "Subject Name",
"type": "text",
"id": "subjectName",
"value": "TigerC",
"firstName": "Tiger",
"lastName": "Chan"
},
{
"name": "QC Name",
"type": "hidden",
"id": "qcName",
"value": "ThomasR",
"firstName": "Thomas",
"lastName": "Richard"
}
]
]
Run Code Online (Sandbox Code Playgroud)
HTML
<table class="table table-responsive table-hover" [mfData]="this.records | dataFilter : filterQuery" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
<thead>
<tr>
<th>#</th>
<th>
<mfDefaultSorter by="subjectName">subject Name</mfDefaultSorter>
</th>
<th>
<mfDefaultSorter by="qcPerson">QC Person</mfDefaultSorter>
</th>
</tr>
</thead>
<tbody *ngIf="!isLoading">
<tr class="border" *ngFor="let sample of mf.data; let i='index'">
<td>{{i + 1}}</td>
<ng-container *ngFor="let item of sample">
<td *ngIf="item.id ==='subjectName'">
{{item.firstName}} {{item.lastName}}
</td>
<td *ngIf="item.id ==='qcPerson'">
{{item.firstName}} {{item.lastName}}
</td>
</ng-container>
</tr>
</tbody>
</table>
Run Code Online (Sandbox Code Playgroud)
TYpescript文件
import { Component, OnInit } from '@angular/core';
import { OrderBy } from '../all_services/OrderByPipe';
@Component({
selector: 'app-userdashboard',
templateUrl: './userdashboard.component.html',
styleUrls: ['../header-footer/css/external.style.css']
})
export class UserdashboardComponent implements OnInit {
constructor() {}
ngOnInit() {}
/** Sorting functions */
public data;
public filterQuery = "";
public rowsOnPage = 10;
public sortBy = "subjectName";
public sortOrder = "asc";
public toInt(num: string) {
return +num;
}
}
Run Code Online (Sandbox Code Playgroud)
Datafilterpipe.ts
import * as _ from "lodash";
import {Pipe, PipeTransform} from "@angular/core";
@Pipe({
name: "dataFilter"
})
export class DataFilterPipe implements PipeTransform {
transform(array: any[], query: string): any {
if (query) {
return _.filter(array, row=>row.name.indexOf(query) > -1);
}
return array;
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到了同样的问题.一旦表在DOM中呈现,我就使用了w3school表排序逻辑.
使用angular2-datatable非常流畅,因为我在我的项目中使用相同的数据表.它的使用非常直接,如果您遇到任何问题,请告诉我.
提前致谢.
下面是TS文件中的实现功能.
columnSorter(n) {
let table, rows, switching, i, x, y, shouldSwitch, dir, switchCount = 0;
switching = true;
this.clickSort = !this.clickSort
dir = "asc";
table = document.querySelector('.smallTable');
while (switching) {
switching = false;
rows = table.rows;
for (i = 0; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
if (dir == 'asc') {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
} else if (dir == 'desc') {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
switchCount++;
} else {
if (switchCount == 0 && dir == 'asc') {
dir = 'desc';
switching = true;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在你的HTML表格中,只需在下面添加,其中0是列号.
(click)="columnSorter(0)
Run Code Online (Sandbox Code Playgroud)
使用此库,您必须使用这些输入变量对表进行一次排序:
mfSortBy: any - sort by parameter
mfSortOrder: string - sort order parameter, "asc" or "desc"
Run Code Online (Sandbox Code Playgroud)
您也可以添加此标记以允许用户通过单击对其进行排序:
<mfDefaultSorter by="name">Name</mfDefaultSorter>
Run Code Online (Sandbox Code Playgroud)
要为表创建自定义排序,您只需要对您的json进行排序.在您的情况下,您应该使用您分配给mf.data的内容进行操作.
您可以创建自定义derective,您将为表创建排序器,然后通过单击对数据进行排序.
例如
import {
Directive, ElementRef, AfterViewChecked,
Input, Output, Renderer, EventEmitter
} from '@angular/core';
@Directive({
selector: '[sorter], [defaultSorter]'
})
export class TableSorterDerective implements AfterViewChecked {
@Input()
sorter: {order:string, property:string};
@Output()
sorted = new EventEmitter();
constructor(private el: ElementRef, private renderer: Renderer) {
}
ngAfterViewChecked() {
let element: HTMLElement = this.el.nativeElement;
if(this.sorter){
this.addSorter(element);
}
}
addSorter(column: HTMLElement){
if(!column.classList.contains("custom_sorter")){
column.addEventListener('click', () => this.sendSort(column), false)
column.classList.add("custom_sorter");
}
}
sendSort(element:HTMLElement){
let columns: HTMLElement[] =
Array.prototype.slice.call(element.parentElement.getElementsByTagName('th'), 0);
columns.forEach(element => {
if(!element.classList.contains(this.sorter.property)){
let icon = element.getElementsByTagName('span')[0];
if(icon) icon.remove();
}
});
let icon:HTMLElement = element.getElementsByTagName('span')[0];
if(!icon) icon = this.renderer.createElement(element, 'span');
icon.classList.remove("glyphicon-triangle-bottom")
icon.classList.remove("glyphicon-triangle-top")
icon.classList.remove("glyphicon")
if(this.sorter.order == "asc"){
this.sorter = {order:"desc", property:this.sorter.property}
icon.classList.add("glyphicon")
icon.classList.add("glyphicon-triangle-top")
}else if(this.sorter.order == "desc"){
this.sorter = {order:"asc", property:this.sorter.property}
icon.classList.add("glyphicon")
icon.classList.add("glyphicon-triangle-bottom")
}
this.sorted.emit(this.sorter)
}
}
Run Code Online (Sandbox Code Playgroud)
然后你只需要对emit上的数据进行排序:
<th *ngFor="let col of columns" [sorter]="col.sorting ? {order:'desc', property:col.property} : undefined" (sorted)="transformationsService.sort(filteredData, $event)"</th>
Run Code Online (Sandbox Code Playgroud)
要排序数据只需使用排序功能,例如:
data.sort((a, b) => {
return 0 - (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)
}
Run Code Online (Sandbox Code Playgroud)
如果您需要有关排序功能的帮助,请参阅此问题.
要对数据进行排序,您总是可以使用Lodash非常强大的_.sortBy
:
import * as _ from 'lodash';
const nestedData = [
{ a: { b: 2} },
{ a: { b: 1} },
{ a: { b: 3} }
];
// Outputs ?????[ { a: { b: 1 } }, { a: { b: 2 } }, { a: { b: 3 } } ]?????
_.sortBy(nestedData, item => _.get(item, ['a', 'b']));
Run Code Online (Sandbox Code Playgroud)
它甚至支持按多个字段排序:
import * as _ from 'lodash';
const nestedData = [
{ a: { b: 2 }, c: 'a' },
{ a: { b: 1 }, c: 'b' },
{ a: { b: 1 }, c: 'd'}
];
// Output:
?????// [ { a: { b: 1 }, c: 'b' },?????
?????// { a: { b: 1 }, c: 'd' },?????
?????// { a: { b: 2 }, c: 'a' } ]?????
_.sortBy(nestedData, [item => _.get(item, ['a', 'b']), item => _.get(item, 'c')]);
Run Code Online (Sandbox Code Playgroud)
至于将此添加到当前表中 - 有很多方法可以实现这一点.在将数据传递给表之前对数据进行预排序可能更容易.如果用户单击列标题 - 只需通过适当的数据运行数据_.sortBy
并将其转储回表中?
您可以实现自定义管道,而不是使用 dataTable,它将对数据进行排序,而无需更改原始对象。单击列时您希望如何对数据进行排序。这是简单的代码,希望对您有用。
import { Pipe, PipeTransform } from "@angular/core";
@Pipe({
name: "orderby",
pure: false
})
export class OrderByPipe implements PipeTransform {
transform(array: Array<any>, args?: any) {
let newDataArray:any = [];
if (array.length > 0 && args.value != undefined) {
for (let item of array) {
for (let subItem of item) {
newDataArray.push(subItem);
}
}
newDataArray.sort((a: any, b: any) => {
if ((a.firstName).toLowerCase() < (b.firstName).toLowerCase()) {
return -1 * args.direction;
} else if ((a.firstName).toLowerCase() > (b.firstName).toLowerCase()) {
return 1 * args.direction;
} else {
return 0;
}
});
array = Array.from(newDataArray);
}
return array;
}
}
Run Code Online (Sandbox Code Playgroud)
要从组件调用此管道,请使用如下代码,定义这些变量
isDesc: boolean = false;
direction: number = 1;
filterData = [];
Run Code Online (Sandbox Code Playgroud)
和
orderByMe(toBeSorted: string){
this.isDesc = !this.isDesc;
this.direction = this.isDesc ? 1 : -1;
this.filterData = Array.from(new OrderByPipe().transform( this.records, {
value: toBeSorted, direction: this.direction } ));
}
ngOnInit(){
this.orderByMe('subjectName');
}
Run Code Online (Sandbox Code Playgroud)
在 Html 模板中你可以使用
<table>
<thead>
<tr>
<th>#</th>
<th (click)="orderByMe('subjectName')">subjectName</th>
<th (click)="orderByMe('qcName')">qcPerson</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let record of filterData; let currentIndex = index;">
<td>{{ currentIndex + 1}}</td>
<td>{{ record.firstName }}</td>
<td>{{ record.lastName }}</td>
</tr>
</tbody>
</table>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1406 次 |
最近记录: |