アシアル情報教育研究所・所長の岡本雄樹です。
プログラミングの基本は「順次・分岐・繰り返し」かもしれませんが、アプリ制作の基本は「データの保存と読み出し」ではないでしょうか?
今回はデータの保存と呼び出しを行うアプリの例として、簡単なToDOアプリを公開します。
サンプルアプリのプロジェクト
アプリとデータの関係
今回のサンプルアプリは「ToDoアプリ」なので、一度登録したToDoを一定の間、記憶し続ける必要があります。
値を記録するときに使う技術の一つに、プログラミング入門で学ぶ「変数」の仕組みがあります。
しかし、変数は、プログラムを終了したタイミングでメモリ上から消去されます。
ToDoアプリで、端末やアプリを再起動するたびにデータが消えてしまっては不便です。
そのため、ToDoアプリのようなデータを保持するアプリを制作する場合には、何らかの仕組みで「値」を「永続化」する必要があります。
永続化というと言葉が難しいですが、要はファイルか何かにデータを保存して消えないようにすれば良いわけです。
今回は「WebStorage(ウェブストレージ)」の「LocalStorage(ローカルストレージ)」という仕組みを使用して、データを永続化します。
アプリにおける値の永続化の課題
先ほどファイルと申し上げましたが、プログラムからパソコンやスマホのファイルを読み書きするためには、アクセス権限が必要になります。そして、WebアプリやMonacaアプリから「ファイル」を書き込むのは、ちょっと大変です。
パソコンのファイルを勝手に読み書きするWebサイトとか、作れたら困りますから、仕方ありませんね。
しかしご安心ください、HTML5技術であるLocalStorage(ローカルストレージ)を使えば、特別な権限無しに、約5MBのデータを保存できます。また、「同期処理」なので初心者でも比較的簡単に利用できます(たぶん)。
他にも、クラウドデータベースに値を記録するという選択肢もあります。
HTML側(index.html)
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta http-equiv="Content-Security-Policy" content="default-src * data: gap: content: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
<script src="components/loader.js"></script>
<link rel="stylesheet" href="components/loader.css">
<link rel="stylesheet" href="css/style.css">
<script src="js/config.js" defer></script>
<script src="js/main.js" defer></script>
</head>
<body>
<h1>ToDoアプリ</h1>
<div class="form">
<input type="text" id="name">
<button onclick="addToDo()">追加</button>
</div>
<ul id="ToDoList">
</ul>
</body>
</html>
メインの処理(js/main.js)
// 初期化処理としてToDoを画面に表示
renderToDoList();
// フォームの情報を元にToDoを保存
function addToDo() {
let input = document.getElementById("name").value;
if (input === "") {
return;
}
addStorage(input);
renderToDoList();
document.getElementById("name").value = "";
}
// ToDoリストをHTML表示する
function renderToDoList() {
let ul = document.getElementById("ToDoList");
ul.innerHTML = "";
ToDoList = getStorage();
for (let i = 0; i < ToDoList.length; i++) {
let ToDo = ToDoList[i];
let li = document.createElement("li");
li.textContent = ToDo;
li.dataset.index = i;
li.addEventListener("click", deleteToDo);
ul.appendChild(li);
}
}
// クリックされたToDoを削除する
function deleteToDo() {
deleteStorage(this.dataset.index);
renderToDoList();
}
// ローカルストレージ操作関数群
function getStorage() {
let list = localStorage.getItem("ToDoList");
if (list === null) {
return [];
} else {
return JSON.parse(list);
}
}
function addStorage(item) {
let list = getStorage();
list.push(item);
setStorage(list);
}
function deleteStorage(index) {
let list = getStorage();
list.splice(index, 1);
localStorage.setItem("ToDoList", JSON.stringify(list));
}
function setStorage(list){
localStorage.setItem("ToDoList", JSON.stringify(list));
}
ローカルストレージを使ったToDoアプリの解説
ローカルストレージはキーバリュー型のデータベースになっています。キーとバリューのペアとして情報を複数、記録することができます。
そのままでもToDoアプリのデータベースとして使用できなくもないですが、普通の配列の方が扱いがラクなので、今回は「バリュー」の方にJSON文字列を書き込むことで「配列」として使用しています。
キー:todolist(固定)
バリュー:JSON文字列(配列をJSON文字列化したもの)
また、ローカルストレージ操作関数群を用意することで、コードを細かく分けました。馴れるまでは、ローカルストレージ操作関数群はブラックボックスと見なして、学習は後回しにしてOKです。
ローカルストレージ操作関数群の紹介
関数として呼ぶだけで、文字列をToDoとして記録したり、配列として取得できる関数群です。ローカルストレージの仕組みを理解していなくても全く問題なく利用可能です。
getStorage()
ローカルストレージからToDoの入った『配列』を取り出します。まだ何も記録されていなければ空の配列を返します。
addStorage(item)
ToDoをローカルストレージにToDoとして記録します。
deleteStorage(index)
ローカルストレージから指定した番号のToDoを消去します。
setStorage(list)
配列をローカルストレージにToDoとして保存します。
addStorage()が内部的に使用している関数なので、基本的には、直接使う必要はありません。
ToDoアプリのメインとなる処理及び関数群
addToDo()
入力欄の値を元にToDoを保存します
renderToDoList()
保存されたToDoを読み出してDOMに書き出します。
箇条書きの要素を書き出したり、箇条書きの要素がクリックされたら削除の関数が呼び出されたりするような仕込みを行っているため、行数はちょっと長めです。
deleteToDo()
画面上でクリックされたToDoを削除します。
この関数が呼び出されるよう、renderToDoListに仕込みを行っています。具体的には、イベントリスナーという仕組みを使い、ToDoのHTML要素がonClickされた時点でdeleteToDo()を呼ぶようになっています。また、ToDoのHTML要素にはdata属性を使って配列のキーが設定されているため、そのキーを参照して値の削除を行っています。
アプリの挙動
初期化のタイミングでrenderToDoList()を実行し、画面にToDoを書き出しています。また、フォーム入力からToDoが追加されるタイミングで、再度、renderToDoList()を呼ぶことで最新のToDo一覧を画面に書き出しています。そして、ToDoを削除するタイミングでも、再度、renderToDoList()を呼ぶことで最新のToDo一覧を画面に書き出しています。
つまり、ローカルストレージに保存されたデータの状態に応じて、毎回、画面を書き換えています。
なお、フレームワークを使ったアプリ開発では、データの状態が変わったタイミングで自動的に画面を書き換えるような処理が、フレームワークの仕組みとして提供されている場合があります。