ionicを試す 17日目 *ngIfを使ってカテゴリー名の表記
ionic infoによる現環境情報です。
PS C:\MyTest\test000> ionic info
Ionic:
Ionic CLI : 6.19.0 (C:\Users\mytes\AppData\Roaming\npm\node_modules\@ionic\cli)
Ionic Framework : @ionic/angular 6.1.1
@angular-devkit/build-angular : 13.2.6
@angular-devkit/schematics : 13.2.6
@angular/cli : 13.2.6
@ionic/angular-toolkit : 6.1.0
Utility:
cordova-res : not installed globally
native-run : not installed globally
System:
NodeJS : v16.14.2 (C:\Program Files\nodejs\node.exe)
npm : 8.5.0
OS : Windows 10
今回でピザ―オーダー画面もどきは終了です。
最後の課題に当たっては、幾つか方法を考えましたが、コピーした配列に手を加える方法が良いと結論付けました。
今回の例は16行程度のテーブルですが、これが数千行を超えるようでしたら、表示用の配列を用意して処理するのが現実的かと思います。
まずMenu配列の定義の下で、MenuCopy配列を用意します。
---------------------------------------------------------------
//メニューコピー配列
//前回までMenu配列を使用していたところは、MenuCopy配列に変更する
MenuCopy = JSON.parse(JSON.stringify(this.Menu));
---------------------------------------------------------------
次にコンストラクター内で、カテゴリー名表示のための行を追加します。
---------------------------------------------------------------
//MenuCopyにカテゴリー名を表示させるためだけの行を追加
let PreviousCategoryName = this.MenuCopy[this.MenuCopy.length-1].category_name;
for(let i=this.MenuCopy.length;i>0;i--){ //行を追加させるので逆順でループ
if(this.MenuCopy[i-1].category_name != PreviousCategoryName){
this.MenuCopy.splice(i,0,{val: '', category_id: '', category_name: PreviousCategoryName, sub_id: ''});
PreviousCategoryName = this.MenuCopy[i-2].category_name;
}
}
//最初のカテゴリーはループ外で追加
this.MenuCopy.splice(0,0,{val: '', category_id: '', category_name: PreviousCategoryName, sub_id: ''});
---------------------------------------------------------------
前のカテゴリー名と変わったら、カテゴリー名表示のための行を追加しますが、
・行が増えていくので、通常とは異なり最後の行から先頭の行へとループさせる
・配列.splice()の第二変数を0あるいは負の数にすると配列の追加が出来る
(第三引数で内容指定)
・最後の追加はループ外で行う必要がある
と言った点に注意が必要です。
その他の関数と"home.page.html"で使用していたMenu配列の部分は、すべてMenuCopy配列に書き換えます。
次に"src\app\home\home.page.html"側の変更です。
上で追加したカテゴリー名表示のための行は、category_name以外は長さ0の文字列ですので、それを判定条件にして表示の切り替えを行います。
Angularの機能で、あるHTMLタグを表示・非表示を切り替える方法は、"*ngIf"と"[hidden]"があります。
(Angularのバージョンによっては異なる方法もありますのでご注意ください。)
------------------------------------------
<span *ngIf=true>表示される①</span>
<span *ngIf=false>表示されない②</span>
<span [hidden]=true>表示されない③</span>
<span [hidden]=false>表示される④</span>
------------------------------------------
この2つにはかなり大きな違いがあります。
"*ngIf"の方は、表示しない場合、その部分を削除します。
IDがあっても、javascriptで探すことは出来ません。(存在しないので)
また、そこの場所でクリックイベント等を定義していた場合、表示・非表示の切り替えでイベントによる関数は動かない事もあり得ます。
条件が満たされ、表示する場合は、改めて、その部分を再作成します。
ですので、場合によってはより重たい表示になるかもしれません。
"[hidden]"の方は、見えないだけでそこにあります。
状況によって使い分けるべきですが、"[hidden]"の方が無難な場合は多いかもしれません。
テーブルのソースの部分は以下の通りです。
今回はあえて"*ngIf"を使用
---------------------------------------------------------------
<tr *ngFor="let entry of MenuCopy; index as index; first as first; ">
<td *ngIf="entry.category_id==''" colspan="4">{{entry.category_name}}</td>
<td *ngIf="entry.category_id!=''"><ion-checkbox [id]="'chkOrder' + index" *ngIf="ForTable[index]!=''" (mousedown)="fnChangeOrderCheck(index, $event)"></ion-checkbox></td>
<td *ngIf="entry.category_id!=''">{{ForTable[index]}}</td>
<td *ngIf="entry.category_id!=''"><ion-checkbox [id]="'chkMenu' + index" (click)="fnChangeMenuCheck(index)"></ion-checkbox></td>
<td *ngIf="entry.category_id!=''">{{entry.val}}</td>
</tr>
---------------------------------------------------------------
ちょっと詰め込み過ぎた気もするピザオーダー画面でしたが、参考になる部分を生かすことが出来れば幸いです。




