環境
- Windows 10 Pro 1909
- Oracle VM VirtualBox 6.1.4 (2020/02/19)
- Oracle VM VirtualBox 6.1.4 Extension Pack
- CentOS Linux 7 (1908) (2019/09/17)
- Git 2.22.2 (IUS版)
- Google Chrome
- Oracle Java SE Development Kit 11.0.6 (2020/01/14)
- Apache Tomcat 9.0.29 (2019/11/21)
- Apache 2.4.6 (2013/07/22)
- nvm v0.35.2 (2019/12/18)
- node v12.16.0 (npm v6.13.4) (2020/02/11)
- Angular CLI 8.3.25 (2020/02/06)
- Visual Studio Code 1.42.1 (2020/02/11)
- Eclipse IDE for Enterprise Java Developers 2019-12 R (4.14.0)
- Spring Tool Suite 4 (4.5.0) (2019/12/19)
目次
- Angularプロジェクトを作成する
- Angular CLIのコマンドでプロジェクトを作成する
- このプロジェクトにPrimeNGをインストールする
- このプロジェクトにPrimeIconsをインストールする
- このプロジェクトに@angular/cdkをインストールする
- PrimeNGのテーブルを複数の列でソートする
- CSSをインポートする
- モジュールをインポートする
- HTMLを記述する
- コードを記述する
- サーバーにデプロイする
ディレクトリ構成
/ +-home | +-mizuki | +-.nvm | | +-versions | | +-node | | +-v12.16.0 | | | +-opt | | +-eclipse-jee -> /home/mizuki/opt/eclipse-jee-201912 | | | | | |-eclipse-jee-201912 | | | +-workspace | | +-angular | | | +-custom-sort | | | +-node_modules | | | | +-primeng | | | | +-primeicons | | | | +-@angular/cdk | | | | | | | |-package-lock.json | | | | | | | +-src | | | +-app | | | | +-class | | | | | |-row-item.ts | | | | | |-sort-item.ts | | | | | | | | | +-enum | | | | | |-sort-order.enum.ts | | | | | | | | | |-app.component.css | | | | |-app.component.html | | | | |-app.component.ts | | | | | | | | | |-app.module.ts | | | | | | | |-styles.css | | | | | +-node_modules | | | +-@angular | | | +-@angular-devkit | | | | | |-package-lock.json | | | +-www | +-html | +-static | |-index.html | +-media | +-sf_sharedfolder | +-opt |-apache-tomcat -> /opt/apache-tomcat-9.0.29 | +-apache-tomcat-9.0.29 | +-bin | | |-startup.sh | | |-shutdown.sh | | |-setenv.sh | | | +-conf | |-tomcat-users.xml | |-java -> /opt/oracle-jdk-11.0.6 | +-oracle-jdk-11.0.6 +-bin |-java
GitHub repository
1. Angularプロジェクトを作成する
1-1. Angular CLIのコマンドでプロジェクトを作成する
$ pwd /home/mizuki/workspace/angular $ npx ng new custom-sort ? Would you like to add Angular routing? (y/N) [y] ? Which stylesheet format would you like to use? (Use arrow keys) [CSS] > CSS SCSS [ https://sass-lang.com/documentation/syntax#scss ] Sass [ https://sass-lang.com/documentation/syntax#the-indented-syntax ] Less [ http://lesscss.org ] Stylus [ http://stylus-lang.com ]
1-2. このプロジェクトにPrimeNGをインストールする
プロジェクトのディレクトリでインストールを行う。
$ pwd /home/mizuki/workspace/angular/custom-sort インストール可能なバージョンを調べる。 $ npm info primeng versions [ '8.1.0', '8.1.1', '8.1.3', '8.1.4', ] バージョンを指定してインストールする。 $ npm install primeng@8.1.4 インストールされたバージョンを確認する。 $ npm ls primeng custom-sort@0.0.0 /home/mizuki/workspace/angular/custom-sort └── primeng@8.1.4
参考
1-3. このプロジェクトにPrimeIconsをインストールする
プロジェクトのディレクトリでインストールを行う。
$ pwd /home/mizuki/workspace/angular/custom-sort インストール可能なバージョンを調べる。 $ npm info primeicons versions [ '1.0.0', '2.0.0' ] バージョンを指定してインストールする。 $ npm install primeicons@2.0.0 インストールされたバージョンを確認する。 $ npm ls primeicons custom-sort@0.0.0 /home/mizuki/workspace/angular/custom-sort └── primeicons@2.0.0
1-4. このプロジェクトに@angular/cdkをインストールする
プロジェクトのディレクトリでインストールを行う。
$ pwd /home/mizuki/workspace/angular/custom-sort インストール可能なバージョンを調べる。 $ npm info @angular/cdk versions [ '8.2.0', '8.2.1', '8.2.2', '8.2.3', ] バージョンを指定してインストールする。 $ npm install @angular/cdk@8.2.3 インストールされたバージョンを確認する。 $ npm ls @angular/cdk custom-sort@0.0.0 /home/mizuki/workspace/angular/custom-sort └── @angular/cdk@8.2.3
2. PrimeNGのテーブルを複数の列でソートする
2-1. CSSをインポートする
src/styles.css
@import url("../node_modules/primeicons/primeicons.css"); @import url("../node_modules/primeng/resources/themes/nova-light/theme.css"); @import url("../node_modules/primeng/resources/primeng.min.css");
参考
2-2. モジュールをインポートする
1つのモジュールをインポートする。
import { TableModule } from 'primeng/table';
src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { TableModule } from 'primeng/table'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, TableModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
2-3. HTMLを記述する
src/app/app.component.html
<p-table [value]="rowList" [style]="{'width':'330px'}"> <ng-template pTemplate="header"> <tr> <th> <div style="width:100%;height:100%;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;"> <span style="flex-grow:1;">column1</span> <i *ngIf="sortOrderColumn1 === SORT_ORDER_ASC" class="pi pi-sort-numeric-down" (click)="onSort(1)"></i> <i *ngIf="sortOrderColumn1 === SORT_ORDER_DESC" class="pi pi-sort-numeric-up" (click)="onSort(1)"></i> </div> </th> <th> <div style="width:100%;height:100%;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;"> <span style="flex-grow:1;">column2</span> <i *ngIf="sortOrderColumn2 === SORT_ORDER_ASC" class="pi pi-sort-numeric-down" (click)="onSort(2)"></i> <i *ngIf="sortOrderColumn2 === SORT_ORDER_DESC" class="pi pi-sort-numeric-up" (click)="onSort(2)"></i> </div> </th> <th> <div style="width:100%;height:100%;display:flex;flex-direction:row;justify-content:flex-start;align-items:center;"> <span style="flex-grow:1;">column3</span> <i *ngIf="sortOrderColumn3 === SORT_ORDER_ASC" class="pi pi-sort-numeric-down" (click)="onSort(3)"></i> <i *ngIf="sortOrderColumn3 === SORT_ORDER_DESC" class="pi pi-sort-numeric-up" (click)="onSort(3)"></i> </div> </th> </tr> </ng-template> <ng-template pTemplate="body" let-row> <tr> <td>{{row.column1}}</td> <td>{{row.column2}}</td> <td>{{row.column3}}</td> </tr> </ng-template> </p-table>
2-4. コードを記述する
src/app/class/row-item.ts
$ pwd /home/mizuki/workspace/angular/custom-sort $ npx ng generate class class/row-item
export class RowItem { column1: string; column2: string; column3: string; }
src/app/class/sort-item.ts
$ pwd /home/mizuki/workspace/angular/custom-sort $ npx ng generate class class/sort-item
export class SortItem { columnIndex: number; order: string; compare: Function; }
src/app/enum/sort-order.enum.ts
$ pwd /home/mizuki/workspace/angular/custom-sort $ npx ng generate enum enum/sort-order
export enum SortOrder { ASC = 'asc', DESC = 'desc' }
src/app/app.component.ts
import { Component, OnInit } from '@angular/core'; import { RowItem } from './class/row-item'; import { SortItem } from './class/sort-item'; import { SortOrder } from './enum/sort-order.enum'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { rowList: RowItem[]; sortOrderColumn1: string; sortOrderColumn2: string; sortOrderColumn3: string; defaultOrderList: SortItem[]; SORT_ORDER_ASC: string; SORT_ORDER_DESC: string; constructor() { this.defaultOrderList = this.getDefaultOrderList(); this.SORT_ORDER_ASC = SortOrder.ASC; this.SORT_ORDER_DESC = SortOrder.DESC; } ngOnInit() { this.rowList = this.getRowList(); this.sortOrderColumn1 = SortOrder.ASC; this.sortOrderColumn2 = SortOrder.ASC; this.sortOrderColumn3 = SortOrder.ASC; this.sortRowList(); } getDefaultOrderList(): SortItem[] { let list: SortItem[] = []; let item: SortItem; item = new SortItem(); item.columnIndex = 1; item.order = SortOrder.ASC; item.compare = function(a: RowItem, b: RowItem): number { if (a.column1 < b.column1) { return -1; } if (a.column1 > b.column1) { return 1; } return 0; }; list.push(item); item = new SortItem(); item.columnIndex = 2; item.order = SortOrder.ASC; item.compare = function(a: RowItem, b: RowItem): number { if (a.column2 < b.column2) { return -1; } if (a.column2 > b.column2) { return 1; } return 0; }; list.push(item); item = new SortItem(); item.columnIndex = 3; item.order = SortOrder.ASC; item.compare = function(a: RowItem, b: RowItem): number { if (a.column3 < b.column3) { return -1; } if (a.column3 > b.column3) { return 1; } return 0; }; list.push(item); return list; } getRowList(): RowItem[] { let list: RowItem[] = []; let item: RowItem; item = new RowItem(); item.column1 = 'あ'; item.column2 = 'a'; item.column3 = '1'; list.push(item); item = new RowItem(); item.column1 = 'あ'; item.column2 = 'a'; item.column3 = '2'; list.push(item); item = new RowItem(); item.column1 = 'あ'; item.column2 = 'b'; item.column3 = '3'; list.push(item); item = new RowItem(); item.column1 = 'い'; item.column2 = 'b'; item.column3 = '4'; list.push(item); item = new RowItem(); item.column1 = 'い'; item.column2 = 'c'; item.column3 = '5'; list.push(item); item = new RowItem(); item.column1 = 'い'; item.column2 = 'c'; item.column3 = '6'; list.push(item); return list; } onSort(columnIndex: number) { this.sortRowList(columnIndex); } sortRowList(columnIndex: number = -1) { let firstOrder: SortItem[] = this.defaultOrderList.filter((item) => item.columnIndex === columnIndex); if (firstOrder.length > 0) { firstOrder[0].order = (firstOrder[0].order === SortOrder.ASC) ? SortOrder.DESC : SortOrder.ASC; switch(columnIndex) { case 1: this.sortOrderColumn1 = firstOrder[0].order; break; case 2: this.sortOrderColumn2 = firstOrder[0].order; break; case 3: this.sortOrderColumn3 = firstOrder[0].order; break; } } let customOrderList: SortItem[] = [ ...firstOrder, ...this.defaultOrderList.filter((item) => item.columnIndex !== columnIndex) ]; this.rowList.sort((a: RowItem, b: RowItem): number => { for (let order of customOrderList) { let compareResult: number = order.compare(a, b); if (compareResult !== 0) { return (order.order === SortOrder.ASC) ? compareResult : -(compareResult); } } return 0; }); this.rowList = [...this.rowList]; } }
2-5. サーバーにデプロイする
リリース用のファイルを作成する。
$ pwd /home/mizuki/workspace/angular/custom-sort $ npx ng build --prod
distディレクトリ配下にプロジェクト名のディレクトリとファイルが出力される。
$ pwd /home/mizuki/workspace/angular/custom-sort/dist/custom-sort $ ls -al 合計 2704 drwxrwxr-x. 2 mizuki mizuki 4096 3月 8 22:36 . drwxrwxr-x. 3 mizuki mizuki 25 3月 8 22:36 .. -rw-rw-r--. 1 mizuki mizuki 16752 3月 8 22:36 3rdpartylicenses.txt -rw-rw-r--. 1 mizuki mizuki 10355 3月 8 22:36 color.c7a33805ffda0d32bd2a.png -rw-rw-r--. 1 mizuki mizuki 948 3月 8 22:36 favicon.ico -rw-rw-r--. 1 mizuki mizuki 293 3月 8 22:36 hue.0614c27197fc3ce572e1.png -rw-rw-r--. 1 mizuki mizuki 806 3月 8 22:36 index.html -rw-rw-r--. 1 mizuki mizuki 13112 3月 8 22:36 line.567f57385ea3dde2c9ae.gif -rw-rw-r--. 1 mizuki mizuki 9427 3月 8 22:36 loading.8732a6660b528fadfaeb.gif -rw-rw-r--. 1 mizuki mizuki 765056 3月 8 22:36 main-es2015.37601e2170bdc46ec6f5.js -rw-rw-r--. 1 mizuki mizuki 864239 3月 8 22:36 main-es5.37601e2170bdc46ec6f5.js -rw-rw-r--. 1 mizuki mizuki 27604 3月 8 22:36 open-sans-v15-latin-300.177cc92d2e8027712a8c.ttf -rw-rw-r--. 1 mizuki mizuki 55181 3月 8 22:36 open-sans-v15-latin-300.27ef0b062b2e221df16f.svg -rw-rw-r--. 1 mizuki mizuki 18280 3月 8 22:36 open-sans-v15-latin-300.521d17bc9f3526c690e8.woff -rw-rw-r--. 1 mizuki mizuki 14564 3月 8 22:36 open-sans-v15-latin-300.60c866748ff15f5b347f.woff2 -rw-rw-r--. 1 mizuki mizuki 15545 3月 8 22:36 open-sans-v15-latin-300.76b56857ebbae3a5a689.eot -rw-rw-r--. 1 mizuki mizuki 15667 3月 8 22:36 open-sans-v15-latin-700.148a6749baa5f658a451.eot -rw-rw-r--. 1 mizuki mizuki 55652 3月 8 22:36 open-sans-v15-latin-700.2e00b2635b51ba336b4b.svg -rw-rw-r--. 1 mizuki mizuki 18476 3月 8 22:36 open-sans-v15-latin-700.623e3205570002af47fc.woff -rw-rw-r--. 1 mizuki mizuki 28192 3月 8 22:36 open-sans-v15-latin-700.7e08cc656863d52bcb5c.ttf -rw-rw-r--. 1 mizuki mizuki 14720 3月 8 22:36 open-sans-v15-latin-700.d08c09f2f169f4a6edbc.woff2 -rw-rw-r--. 1 mizuki mizuki 56266 3月 8 22:36 open-sans-v15-latin-regular.7aab4c13671282c90669.svg -rw-rw-r--. 1 mizuki mizuki 15050 3月 8 22:36 open-sans-v15-latin-regular.9dce7f01715340861bdb.eot -rw-rw-r--. 1 mizuki mizuki 17704 3月 8 22:36 open-sans-v15-latin-regular.bf2d0783515b7d75c35b.woff -rw-rw-r--. 1 mizuki mizuki 26488 3月 8 22:36 open-sans-v15-latin-regular.c045b73d86803686f4cd.ttf -rw-rw-r--. 1 mizuki mizuki 14048 3月 8 22:36 open-sans-v15-latin-regular.cffb686d7d2f4682df83.woff2 -rw-rw-r--. 1 mizuki mizuki 118 3月 8 22:36 password-meter.d59e6dc2616c53ce8e77.png -rw-rw-r--. 1 mizuki mizuki 37053 3月 8 22:36 polyfills-es2015.5b10b8fd823b6392f1fd.js -rw-rw-r--. 1 mizuki mizuki 129362 3月 8 22:36 polyfills-es5.3e8196928d184a6e5319.js -rw-rw-r--. 1 mizuki mizuki 39748 3月 8 22:36 primeicons.2d2afb2719a1ee903e57.eot -rw-rw-r--. 1 mizuki mizuki 39648 3月 8 22:36 primeicons.66ee0deb739ca71f0ecd.woff -rw-rw-r--. 1 mizuki mizuki 39572 3月 8 22:36 primeicons.df0140f8e79ecfeffaf8.ttf -rw-rw-r--. 1 mizuki mizuki 163568 3月 8 22:36 primeicons.e5e0e94474d5fd92e7e8.svg -rw-rw-r--. 1 mizuki mizuki 1485 3月 8 22:36 runtime-es2015.c5fa8325f89fc516600b.js -rw-rw-r--. 1 mizuki mizuki 1485 3月 8 22:36 runtime-es5.c5fa8325f89fc516600b.js -rw-rw-r--. 1 mizuki mizuki 171599 3月 8 22:36 styles.699e9cf8808c28ae8c28.css
index.htmlのbase hrefを変更する。デフォルトではサーバールートを基準にして相対パスの解決が行われてしまう。
<base href="/">
<base href="/code/2020/03/dist/0801/">
プロジェクト名のディレクトリ配下にあるファイルをサーバーにアップロードする。
参考