Node.jsでメモアプリを作って遊ぶ(そのに)


前回に引き続き、Node.jsの練習で作ったメモアプリについてのざっくり解説。今回はメモのデータをPOSTするところの話を中心にやってこうかねー。

POSTする仕組みを作る

<div id="create-memo">
    <ul>
        <li>
            <p class="caption">Title</p>
            <input type="text" name="memoname" id="">
        </li>
        <li>
            <p class="caption">Memo text</p>
            <textarea name="memotext" id="" cols="30" rows="10"></textarea>
        </li>
        <li>
            <input type="button" id="memo_create" value="SAVE">
            <input type="button" id="memo_delete" value="DELETE">
        </li>
    </ul>
</div>

前回作ったテンプレの「index.ejs」に、上記のようなタグを入れる。なんか完全に個人的な好みなのだが、<form>を予めHTMLタグとして書いておくより、Javascriptで動的に生成する方が好きなので今回もそうしてみた。「SAVE」ボタンを押したらPOSTで新規作成または上書き、「DELETE」ボタンを押したらPOSTで削除ってな感じの動作をさせたい。

$("input#memo_create").click(function(){
    // 動的にフォーム作ってPOSTする
    let file_name = $("input[name=memoname]").val();
    let file_text = $("textarea[name=memotext]").val();
    let $form = $("
").attr({"action": "/", "method":"post"});
    $form.append($("<input type="text">").attr({"type":"hidden", "name":"memoname", "value": file_name}));
    $form.append($("<input type="text">").attr({"type":"hidden", "name":"memotext", "value": file_text}));
    $form.appendTo(document.body);
    $form.submit();
});
// DELETEボタンをクリック
$("input#memo_delete").click(function(){
    // 動的にフォーム作ってPOSTする
    let file_name = $("input[name=memoname]").val();
    let $form = $("
").attr({"action": "/", "method":"post"});
    $form.append($("<input type="text">").attr({"type":"hidden", "name":"isdelete", "value": file_name}));
    $form.appendTo(document.body);
    $form.submit();
});

続いてスクリプト部分。jQueryを使って動的にフォームを作ってBODYにぶちこんでるのだが、SAVEボタンをクリックした場合は「memoname(ファイル名)」と「memotext(本文テキスト)」、DELETEボタンを押した場合は「isdelete」にファイル名をぶちこんでPOSTする。

POSTに対するイベントを作る

// POST
app.post("/", function(req,res){
    // postされた情報で処理を分岐(ごりおし)
    if(req.body.isdelete == undefined){
        console.log("new memo file is '" + req.body.memoname+"'");
        // メモ書き込み
        fs.writeFile(memo_path+"/"+req.body.memoname, req.body.memotext, function(err){
            if(err){
                // エラーだったらなんかする
            }

            // レンダリング
            rendering(res);            
        });
    } else {
        // 指定のファイルを削除
        console.log("delete memo file is '" + req.body.isdelete+"'");
        // メモ削除
        fs.unlink(memo_path+"/"+req.body.isdelete, function(err){
            if(err){
                // エラーだったらなんかする    
            }

            // レンダリング
            rendering(res);
        });
    }
});

app.jsではPOSTされた情報を基にファイルを書き込んだり、削除したりする。ここで受けた「res.body」以下がPOSTされたデータが格納されてる配列になってるので、そいつを見ながら処理してやると良さげ。とりま動けばOKなので例によって例のごとくエラーハンドル全力放棄や!

書いたメモを読み込む

ここまで作って「そういえば肝心のメモ読み込む処理作ってなかったぜ!」てのに気づいた。こいつはJavascriptで非同期に取得して読み込む事に。

// メモ一覧のリストをクリック
$("div#list_memo li").click(function(){
    // liの内容(ファイル名)を取得
    let file = $(this).text();
    $.get("memo/"+file, function(data){
        $("input[name=memoname]").val(file);    // ファイル名と
        $("textarea[name=memotext]").val(data); // テキストデータをフォームに反映
    });
});

まず、index.ejsのスクリプト部分。リストに列挙されているファイル名をクリックしたら、そいつに対してGETでリクエスト投げて、レスポンス帰ってきたらinputだとかtextareaにファイル名とデータテキストを反映させたい。だけれどもちろん、これ書いただけだとサーバ側が「あ?ねぇよそんなもん」と言ってファイルを返してくれない。

// memo以下のリクエストはテキストとして取得(ajaxアクセス用)
app.get("/memo/:filename", function(req,res){
    // param[0]に入ってるファイル名を取り出す
    let param = req.params;
    // メモを読み込み
    fs.readFile(memo_path+"/"+param["filename"], "utf-8", function(err, data){
        if(err){
            // なんかエラーハンドル
        } else {
            // 読み込んだデータを送る
            res.send(data);
        }
    });
});

なのでapp.js側に、memoフォルダ以下にアクセスあったらテキストの中身を返すように書いておく。Expressの公式ドキュメントを見る限り、リクエストURL内にある「:某」の部分を抽出して、req.paramsで取得できるらしい。なので、今回は「/memo/ファイル」の「ファイル」部分を抽出して読み込んで、GETしたときにそいつをクライアントに送るようにしといた。

Vue.js?なにそれおいしいの?

思うがままに走り書きした結果、当初想定してた機能はそれとなく搭載できたのだが、実装するためにネットで調べ物してみると「jQueryからVue.jsに乗り換えてやったぜハッハー!」的な記事をちょいちょい目にしたので、本当に今のままの実装でええんやろか?というのが引っかかってる。フロントエンドのJavascriptライブラリは栄枯盛衰なのだけれど、どーやら最近流行ってるらしいので気になるのよねぇ。

なんか長いことjQueryにお世話になってきたけど、ナウいライブラリを使えばもうちょいスタイリッシュに書けちゃうかもしんないので、次回はjQueryで書いてる部分をVue.jsとやらに置き換えて遊んでみようかねー。ということで、もうちっとだけ続くんじゃ。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)