javascript - ディープコピー - 入れ子になったJSONからのAngular 4データテーブルソート




angular2 ディープコピー (3)

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;
     }
    }           

コンポーネントからこのパイプを呼び出すには、次のようにコードを使用して、これらの変数を定義します。

isDesc: boolean = false;
direction: number = 1;
filterData = [];

そして

  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');
  }

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>

入れ子になったデータを持つAngularデータテーブルに関するヘルプが必要です。

テーブル内のデータを並べ替えます。

https://www.npmjs.com/package/angular2-datatable - 私はからデータテーブルを使用してい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"
    }
  ]
]

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>

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;
    }
}

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;
    }
}

このライブラリを使用すると、これらの入力変数を使用してテーブルを一度ソートする必要があります。

mfSortBy: any - sort by parameter
mfSortOrder: string - sort order parameter, "asc" or "desc"

また、このタグを追加して、ユーザーがクリックしてソートできるようにすることもできます。

<mfDefaultSorter by="name">Name</mfDefaultSorter>

テーブルのカスタムソートを作成するには、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)
  }
}

そして、あなたはemitのデータをソートする必要があります。

    <th *ngFor="let col of columns" [sorter]="col.sorting ? {order:'desc', property:col.property} : undefined" (sorted)="transformationsService.sort(filteredData, $event)"</th>

データをソートするには、単にsort関数を使用してください。

data.sort((a, b) => {
        return 0 - (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)
      }

ソート機能について助けが必要な場合は、 この質問を参照してください。


私は同じ問題に直面していました。 テーブルがDOMでレンダリングされたら、 w3schoolテーブルソートロジックを使用しw3school

私のプロジェクトで同じdatatableを使っているので、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;
        }
      }
    }
  }

あなたのHTMLテーブルには、0を列番号として、以下を追加してください。

(click)="columnSorter(0)






nested