web-dev-qa-db-ja.com

PrimeNG DataTableカスタムソートまたはフィルタリング(Angular 2)

PrimeNgDatatableの日付列の並べ替え/フィルタリングで問題が発生しています。日付 "dd/mm/yyyy"文字列を表示しているためです。

  1. テンプレートを使用して「dd/mm/yyyy」を表示する場合、フィルターは、日付ISO形式の実際のデータバインドで機能するフィルターとして機能しません。
  2. データをバックエンドから文字列形式に変換する場合、日付ではなく文字列で並べ替えるため、並べ替えは正しくありません。
4
Rohit Sindhu

私はmoment.jsを使用してこの問題を解決しました。これは、より簡単で高速だからですが、フレームワークなしで実行したい場合は、いつでもコードを少しカスタマイズできます(条件と文字列変換の場合はもう少し欲しいです)

したがって、moment.jsをプロジェクトに追加する必要があります。a)このサイトからメインのhtmlインデックスファイル(main angularセレクター、ポリフィルなど)にsrcリンクを追加する) https://cdnjs.com/libraries/moment.js/ b)ただし、本番環境の場合は、npm経由で追加することをお勧めします。 http://momentjs.com/docs/ 他の可能性もあります。

次に、インポートステートメントの下および@Componentアノテーションの上でモーメント変数を宣言する必要があります

declare var moment;

次に、すでにprimengモジュールがプロジェクトに追加されている場合、primengの​​p-dataTableタグ内のhtmlファイルにp-columnタグがあり、このタグ内にsortable = "custom"と(sortFunction)= "mysort( $ event) "のように:

<p-column field="date" header="Data" sortable="custom" (sortFunction)="mysort($event)"></p-column>

P列タグで表示される日付はDD.MM.YYYY文字列形式です(例:03.01.2017)

その後、テーブルにデータを表示するために使用される配列にデータをフェッチしてプッシュするコンポーネントで、予定という名前の例では、mysortという名前の関数を追加する必要があります(この関数をhtml p-columnタグで呼び出しているため)

mysort(event) {
    let comparer = function (a, b): number {
      let formatedA = moment(a.date, "DD.MM.YYYY").format('YYYY-MM-DD');
      let formatedB = moment(b.date, "DD.MM.YYYY").format('YYYY-MM-DD');
      let result: number = -1;

      if (moment(formatedB).isBefore(formatedA, 'day')) result = 1;
      return result * event.order;
    };

    this.appointments.sort(comparer);
}

私の例では、a.dateとb.dateは「21.12.2016」のような文字列であり、YYYY-MM-DDにフォーマットする必要があります。次に、日付を比較しているだけです。

そしてそれだけで、私はこのコードをチェックしました、そしてそれは働きます。それが誰かの助けになることを願っています、そして説明がチュートリアルスタイルで書かれていたらすみませんが、これは私の最初の答えであり、私はそれを正しい方法でやりたかったです:)

10
Relis

Relisと同じように解決しました。ただし、「this.appointments」変数を再割り当てするまで機能しませんでした。

  mysort(event) {

     this.appointments.sort((appointmentA, appointmentB) => {

     // Here the property date is a date string with the format 'dd/mm/yyyy'. 
     // In the constructor of moment(), the second paramater is 
     // the format of the string you're passing in.
     const momentA = moment(appointmentA.date, 'dd/mm/yyyy');
     const momentB = moment(appointmentB.date, 'dd/mm/yyyy');

     if(momentB.isBefore(momentA)){
       result = 1;
     }

     return result * event.order;
   });

    // This is the key here.
    this.appointments = [...this.appointments];
    }
1
jriver27

少し異なる問題を解決するために@Relisを使用しましたが、最初は役立つ回答を@Relisに感謝します。質問に関しては、ヘッダーがクリックされるたびに日付を変換するように強制する追加の関数やコールバックがなくても、これは解決できると思います。モデルと表現を分離する必要があります(データテーブルにデータを表示するための並べ替えと表現のモデル)日付プロパティを持つオブジェクトの配列があるとします。

let dataArray = [{date:'01/02/2016'},{date:'01/02/2017'}]

次に、追加のプロパティsortableDateを使用して、この配列内のすべてのオブジェクトを拡張できます。

 let dataArray = [{date:'01.02.2016', sortableDate:'2016-02-01'},{date:'01.02.2017', sortableDate:'2017-02-01'}]

変換には、 moment.js を使用することもお勧めします。これで、プロパティの1つを使用して値を表示し、別のプロパティを使用して並べ替えることができます。

<p-column [field]="'mySortableDate'" [header]="'Header name' [sortable]="true">
  <ng-template let-col let-data="rowData" pTemplate="body">
    <span>{{data.date}}</span>
  </ng-template>
</p-column>
0
nitoloz

単にトリック

<p-column field="StartDate" [editable]="true" header="Start Date">
<ng-template let-col let-car="rowData" pTemplate="body">
 <span>{{car[col.field] | date: '  d,MMM,yyyy'}}</span>
</ng-template>                         
 </p-column>
0