Mithril入門

#ゴール
* Mithrilを理解できる
* SPAやMVCフレームワークを理解できる
* mithrilの特徴を理解できる
* mithrilのM,V,Cの使い方を理解できる

---

#目次
* mithrilとは
* シングルページアプリケーション
* MVCフレームワーク
* mithrilの特徴
* mithrilのインストール方法
* シンプルなアプリケーション

---

#mithrilとは
* ミスリル
* シングルページアプリケーションを作るためのクライアントサイドMVCフレームワークである。軽量、信頼性、高速の特徴がある

---

##シングルページアプリケーション

---

###シングルページアプリケーションとは
* 略称：SPA
* ページ全体をレンダリングする代わりに、変更部分だけ書き換えて、nativeアプリと似ていてdataのみをサーバーから取得する

---

###ページ全体をレンダリングする
![Wireframe.png](https://qiita-image-store.s3.amazonaws.com/0/13451/700e87e2-7d03-5a93-dd75-14de63c9ae0d.png)




---

###変更部分だけ書き換える

![変更部分のみ更新.png](https://qiita-image-store.s3.amazonaws.com/0/13451/9afb092a-f234-028f-ec31-41dff7c4794e.png)



---

###dataのみをサーバーから取得する
* 初めての検索
![spa-data1.png](https://qiita-image-store.s3.amazonaws.com/0/13451/7144d122-5b12-07bc-1483-9fdd7a0b36be.png)

---
###dataのみをサーバーから取得する
* jqueryキーワードを追加する
![spa-data2.png](https://qiita-image-store.s3.amazonaws.com/0/13451/9ad72e77-4a08-83e8-da6f-25c2c6dac18c.png)

---
###dataのみをサーバーから取得する
* 画面構成
 * HTML + CSS + JS + data
* 新規
 * HTML + CSS + JS ロード
 * data取得
* 更新
 * data取得のみ

---

##クライアントサイドMVCフレームワーク

---

###クライアントサイドMVCフレームワークとは
* Ruby on Rails
 * Model（モデル）: データベースへのアクセス、SQLコマンドの送信、レコードの取得と管理
 * Controller（コントローラ）: プログラムの制御
 * View（ビュー）: 画面の生成。テンプレート
* JS MVCフレームワーク
 * Model: データモデルの部分
 * View: ユーザーインターフェイスの部分
 * Controller: そしてビューとモデルのあいだで制御する部分

---

###主要なクライアントサイドMVCフレームワークの比較
* [Mithril, Backbone, Angular, React \- 調べる \- Google トレンド](https://trends.google.com/trends/explore?cat=13&q=Angular,React,Backbone,Mithril)
* ![スクリーンショット 2017-03-07 8.04.36.png](https://qiita-image-store.s3.amazonaws.com/0/13451/29889e59-c734-86b0-62f4-465bdecacaa8.png)


---
##特徴 

---

###最速
![スクリーンショット 2017-03-07 8.16.35.png](https://qiita-image-store.s3.amazonaws.com/0/13451/266d3a1e-0bbf-dcd2-d845-7b0214a8c693.png)

* ロード
 * gzip圧縮時でたったの7.8KBで、他への依存がないので、ロードが速い
* レンダリング
 * [画像や画面の内容を指示するデータの集まりをコンピュータプログラムで処理して、具体的な画素の集合を得ること](http://e-words.jp/w/%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0.html)
* 小さくシンプルなAPIと、学習コストが低い


---

##インストール

```html
<!doctype html>
<title>ToDoアプリケーション</title>
<script src="mithril.min.js"></script>
<script>
//アプリケーションコードはここ
</script>
```

---

##シンプルなアプリケーション

---
###構成
* コンポーネント
* モデル
* ビュー・モデル
* コントローラ
* ビュー
* マウント


---
###ポイント
* データバインディング
* m.prop
* 自動再描画システム



* 補足
 * http://mithril-ja.js.org/getting-started.htmlに参照


---

###コンポーネント
* [コンポーネントはコードを組織化するのに使える多目的なツールで、さまざまな用途がある](http://mithril-ja.js.org/components.html)
* 以下の例をシンプルにするために、このコンポーネントをモデルクラスの名前空間として利用する

```js
var todo = {};
```
---

###モデル
* 複雑なアプリにコンポーネントとモデルの実体が分けられるが、初めてシンプルなアプリを説明するので、モデルの実体をコンポーネントの中に入れましょう。

```js
//Todoクラスはプロパティを2つ持つ
todo.Todo = function(data) {
    this.description = m.prop(data.description);
    this.done = m.prop(false);
};

//TodoListクラスはTodoのリスト
todo.TodoList = Array;
```

---

###ビュー・モデル

```js
todo.vm = {
    init: function() {
        //アクティブなToDoのリスト
        todo.vm.list = new todo.TodoList();

        //新しいToDoを作成する前の、入力中のToDoの名前を保持するスロット
        todo.vm.description = m.prop('');

        //ToDoをリストに登録し、ユーザが使いやすいようにdescriptionフィールドをクリアする
        todo.vm.add = function(description) {
            if (description()) {
                todo.vm.list.push(new todo.Todo({description: description()}));
                todo.vm.description("");
            }
        };
    }
};
```

---
###ビュー・モデル
* モデルレベルのエンティティ
* UIの状態を保持する
* 特定のUI状態に関するロジックのカプセル化を行う

---
###コントローラ
* ビューモデルの初期化

```js
todo.controller = function() {
    todo.vm.init()
}
```



---
###ビュー

```js
todo.view = function() {
    return m("html", [
        m("body", [
            m("input", {onchange: m.withAttr("value", todo.vm.description), value: todo.vm.description()}),
            m("button", {onclick: todo.vm.add}, "Add"),
            m("table", [
                todo.vm.list.map(function(task, index) {
                    return m("tr", [
                        m("td", [
                            m("input[type=checkbox]", {onclick: m.withAttr("checked", task.done), checked: task.done()})
                        ]),
                        m("td", {style: {textDecoration: task.done() ? "line-through" : "none"}}, task.description()),
                    ])
                })
            ])
        ])
    ]);
};
```


---
###ビュー

```js
m("button", {onclick: todo.vm.add}, "Add"),
```

* todo内容を追加する機能
* buttonタグ
* value: "Add"
* onclick属性： todo.vm.add
* 以下と同じ

```js
<button onclick="todo.vm.add()">Add</button>
```

---

###ビュー
```js
m("input", {onchange: m.withAttr("value", todo.vm.description), value: todo.vm.description()})
```

```js
onchange: function(e) {
    todo.vm.description(e.target["value"]);
}
```

```js
<input value="description" />
```

---
###マウント
```js
m.mount(document, {controller: todo.controller, view: todo.view});
```
* todoコンポーネントの初期化
* 自動再描画システムが有効になる


---
###まとめ
![mithril_構成図.png](https://qiita-image-store.s3.amazonaws.com/0/13451/bcf67279-fd24-5033-675b-2bf0e400f91e.png)


---

###m.prop
* getter-setter関数を作るための単純なファクトリ
* Ruby on Rails

```ruby
Class Test
  attr_accessor :name
  
  def initialize(name)
    @name = name
  end
end

test = Test.new("alin")
puts test.name # alin
```

* java

```java
class GetterAndSetter
{
    private int data;

    public int getData()
    {
        return data;
    }

    public void setData( int param )
    {
        data = param;
    }
}

```

---

###m.prop
* 初期化

```js
this.done = m.prop(false);
```

* 使用

```js
 m("input[type=checkbox]", {onclick: m.withAttr("checked", task.done), checked: task.done()})
```

* 画面に初めて描画される時
 * checked = false
* onclickの時
 * htmlのchecked属性値をtask.doneに渡す

---
###データバインディング
```js
m("input", {onchange: m.withAttr("value", todo.vm.description), value: todo.vm.description()})
```

![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/13451/327617de-1356-5b07-cbd8-f9ef7848598e.png)




---
#ご静聴ありがとうございます