LoginSignup
9
9

More than 5 years have passed since last update.

【jQuery】クライアントMVCフレームワーク - Tiny【JavaScript】

Last updated at Posted at 2017-06-02

はじめに

以前作ったものを少し修正したものを作成しました。
導入は、jqueryを読み込んだ後に本ライブラリを読み込むだけです。

ファイルサイズが小さく機能も少なめなので名前はTinyです。

jQueryが少しわかっていれば使えます。
2,3分もあれば使い方が分かるんじゃないでしょうか?
しかも、勝手にクライアントサイドがMVCになります。

TODOを作ってみる

ではTODOをプログラムしてみようと思います。

TODOの仕様ですが
・addボタンでテキスト内容をTODOに追加
・delete allボタンでTODOを全てクリア
といたってシンプルなものです。

TODOをjQueryのみで作ってみる

ではTODOをjQueryのみでMVCで実装しようと思います。

index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>tiny framework test</title>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="js/jquery-3.2.1.min.js"></script>
<script src="js/onlyjquery.js"></script>
</head>
<body>
<h3>TODO only jQuery</h3>
<input id="todo_text" type="text"><br>
<input id="add_button" type="button" value="add">&nbsp;
<input id="delete_all_button" type="button" value="delete all"><br>
<br>
<table id="todo_table">
    <thead><tr><th>todo</th></tr></thead>
    <tbody></tbody>
</table>
</body>
</html>
onlyjquery.js
$(function() {
    // モデル
    var todos = [];

    // addボタンクリック時の処理
    $('#add_button').click(function(e) {
        todos.push($('#todo_text').val());  // モデルを更新
        updateView();   // ビューを更新
    });

    // delete allボタンクリック時の処理
    $('#delete_all_button').click(function(e) {
        todos = []; // モデルを更新
        updateView();   // ビューを更新
    });

    // ビューを更新
    function updateView() {
        var strHtml = '';
        todos.forEach(function(todo) {
            strHtml += '<tr><td>' + todo + '</td></tr>';
        });
        $('#todo_table tbody').html(strHtml);
    }
});

jQueryのみのプログラムを少し説明します。

var todoはモデルです。
イベントハンドラがコントローラで
イベントハンドラで、モデルの更新を行い、モデルの情報のみでビュー(画面)を更新します。

TODOをTinyで作ってみる

次に自作フレームワークTinyを使ってTODOを実装しようと思います。

index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>tiny framework test</title>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="js/jquery-3.2.1.min.js"></script>
<script src="js/jquery.tiny.min.js"></script>
<script src="js/withtiny.js"></script>
</head>
<body>
<h3>TODO with Tiny</h3>
<input id="todo_text" type="text"><br>
<input id="add_button" type="button" value="add">&nbsp;
<input id="delete_all_button" type="button" value="delete all"><br>
<br>
<table id="todo_table">
    <thead><tr><th>todo</th></tr></thead>
    <tbody></tbody>
</table>
</body>
</html>
withtiny.js
$(function() {
    $.Tiny({
        // モデル(変数)
        variable: {
            todos: []
        },
        // イベントハンドラ
        controller: [
            {// addボタンクリック時の処理
                target: '#add_button',
                event: 'click',
                name: 'add'
            },

            {// delete allボタンクリック時の処理
                target: '#delete_all_button',
                event: 'click',
                name: 'delete_all'
            },
        ],
        // モデル変更
        model: {
            init: function(variable) {

            },
            add: function(variable, e, src) {
                variable.todos.push($('#todo_text').val());
            },
            delete_all: function(variable, e, src) {
                variable.todos = [];
            },
        },
        // ビュー更新
        view: {
            init: function(variable) {

            },
            add: function(variable, e, src) {
                this.update(variable, e, src);
            },
            delete_all: function(variable, e, src) {
                this.update(variable, e, src);
            },
            update :function(variable, e, src) {
                var strHtml = '';
                variable.todos.forEach(function(todo) {
                    strHtml += '<tr><td>' + todo + '</td></tr>';
                });
                $('#todo_table tbody').html(strHtml);
            }
        }
    });

});

Tinyの説明

さあ、やっとTinyの説明ができます。

$.Tiny()の引数

  • variables:モデルの定義
  • controller:イベントハンドラ
  • model:モデル変更処理
  • view: ビューの変更処理(モデルのみを参照してビューを更新すること)

をプロパティとするオブジェクトです。では、プロパティ毎に細かく説明します。

variables

モデルを定義します。オブジェクト又は配列である必要があります。
(モデルなので、modelとしようと思いましたがモデルの変更をmodelとしたかったため、variablesにしてしまいました)

controller

イベントハンドラを定義します。
jQueryのonメソッドで
delegateしないパターンとするパターンがありますが

delegateしないパターン
例:$('#add_button').on('click', function() {});

contorller: [
    {
        target: '#add_button',
        event: 'click',
        name: 'add'
    },
    ...
}

delegateするパターン
例:$('body').on('click', 'div', function() {});

contorller: [
    {
        delegator: 'body',
        target: '#div',
        event: 'click',
        name: 'add'
    }
    ...
]

このようにdelegatorが必要な場合は指定してください。
またnameプロパティは必須です。このnameで、モデル変更、ビュー変更を行いますので、
わかりやすい名前を付けたほうが良いと思われます。

model

モデルの変更を行います
contorllerで

contorller: [
    {
        target: '#add_button',
        event: 'click',
        name: 'add'
    },
    ...
]

とした場合、modelは次のように書きましょう。

model: {
    add: function(variable, e, src) {
        // ここでモデル(variable)を変更する
    },
    ...
}

controllerで指定したnameと同じ名前のプロパティを用意しましょう。
variableがモデルですので、ここで変更しましょう。
非同期のプログラムにも対応しています。非同期処理はPromiseで書きましょう。

view

ビュー(画面)の変更を行います。

contorllerで

contorller: [
    {
        target: '#add_button',
        event: 'click',
        name: 'add'
    },
    ...
]

とした場合、viewは次のように書きましょう。

view: {
    add: function(variable, e, src) {
        // ここでモデル(variable)を変更する
    },
    ...
}

controllerで指定したnameと同じ名前のプロパティを用意しましょう。
引数のvariableを参照して画面を変更しましょう。
上の例なら、#add_buttonがクリックされる→モデルの変更(model.add)→ビューの変更(view.add)
といった具合にプログラムが動きます。

テクニック

サンプルのview.updateのようにメソッドを使いまわすことも可能です。(privateのように使えます。)

Tinyのダウンロード

自由に使ってください。
リンク

【最後に】

MVCを利用すると、簡単に言えばプログラムの見通しが良くなります。
variablesだけ見れば、この画面はどのような変数をつっているのか一目瞭然ですし、
ビューがモデルと独立しているので、プログラムの改修も楽なはずです。

9
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9