ionicを試す 13日目 連想配列の存在テスト(と新たな問題の予感)
前回からの続きです。
解決していない問題点
---------------------------------------------------------------
1.メニューのチェックボックスをオン・オフさせるとオーダーの項目が際限なく増える
(今回は1アイテムは一度だけオーダーできることにしたい)
2.解決
3.生地が複数選べるのはおかしい。ソースも一つのみ選択にしたい
4.メニューは並び順になっているのにオーダーの順番がバラバラ
5.オーダー側のチェックを外すとオーダーからアイテムが削除され、メニューのチェックも外したい
6.出来れば生地やソース、トッピングなどのカテゴリー別に並べたい
---------------------------------------------------------------
今回は、問題1.を解決します
複数選べるアイテムかをメニュー配列の属性に持たせる方法もありますが、エラーメッセージを表示せずにシンプルに一つしか選べない方法にしたいと思います。
(コーラが一つしか選べないとか現実的では無いですが)
また、チェックの付いたメニューのチェックとオーダーのチェックのいずれかのチェックが外された場合、オーダーのアイテムが削除されるようにしたいと思います。
この機能のためにまず必要なのは、オーダー配列に追加する前に、そのアイテムと同じものが既にあるかどうかを検索する機能です。
前提として、メニュー配列には"category_id"と"sub_id"の組み合わせは一つしか存在しないとします。
まず、前回の方法でメニューから選ばれたアイテムと同じ値を持つ連想配列を構築します。
(JSON.stringifyとJSON.parseを使う訳です)
以下のコードは、この連想配列tmpObjの"category_id"と"sub_id"を組み合わせたものが配列Orderに存在するかのテストです。
(二つのコードとも文字列として扱っています)
---------------------------------------------------------------
//tmpObjのcategory_idとsub_idの組み合わせが、Order配列に存在するかを調べる。
const intExistIndex = this.Order.findIndex((u) => (u.category_id + u.sub_id)=== (tmpObj.category_id + tmpObj.sub_id));
---------------------------------------------------------------
配列の検索方法は、幾つかあるのですが、このfindIndex()と言うのは、少なくとも一つの要素が指定された関数で実装されたテストに合格するかを調べるのに適しています。
(※このテストの戻り値は、何番目の要素かと言うindexです)
mdn web docs Array.prototype.findIndex()
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
コードを意訳すると
・Order配列の要素"u"をテストする(合格が出るまで、あるいはすべてテストするまで)
・調べるテストは連想配列tmpObjの"category_id"+"sub_id"と同じ"category_id"+"sub_id"があるか?
・なければ-1を、あればその要素のindexをintExistIndex にセットする。
となります。
さて、この関数ですが"home.page.html"の中で(ngModelChange)="fnChangeCheck(index)"として呼び出されています。
つまりメニューの配列のチェックがついたときと外された時のどちらでも呼び出されています。
ですので、メニューのチェックが外された時に、そのアイテムがオーダー配列の中に存在する場合、それを削除するコードも組み込みましょう。
以下のようなコードになります。
---------------------------------------------------------------
//チェックが外され、そのアイテムがOrder配列にあれば削除
if(intExistIndex != -1){
this.Order.splice(intExistIndex,1);
}
---------------------------------------------------------------
splice()と言うのは、配列に対して削除したり追加したり変更したり出来る多彩な命令です。
今回は、intExistIndexの位置の要素を1つ削除と言う命令になっています。
詳しくは以下のサイトを参照してください。
mdn web docs Array.prototype.splice()
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
覚えることは色々あるにせよ、良い感じで出来てきた感じがします。
・
・
・
・
・
残りは、チェックの付いたオーダーのチェックが外された場合、そのアイテムを削除する事ですが、関数は別物になるとしても同様の方法で行けそうな感じがしますね。
そしてここまで来ると問題3.の『生地とソースは一つのみ選択可能』も直せそうな気がします。
と簡単に考えていたのですが、これがなかなか・・・
失敗ではなく経験と考えれば、次回は色々参考になるかもしれません。
次回に続きます。




