LOG

Mithril.js勉強会2回目のメモ

記事の作成日15/08/29
Mithrilのバージョン0.2.0
前回の記事Mithril.js勉強会1回目のメモ
次回の記事Mithril.js勉強会3回目のメモ

routing(ラウティング)に関して

route(ラウト)の定義を定義するには以下の項目が必要

  • ホストとなるDOM要素
  • デフォルトのラウト
  • 遷移する可能性のあるラウトとそれをレンダリングするためのコンポーネントのキー・バリューのマップ

実際に定義をする際はm.route()を利用する

m.route(
    document.body,
    "/user/",
    {
        "/user" : {
            controller(){
                return {text:'default'}
            },
            view(controller){
                return m('div',controller.text);
            }
        },
        "/user/yokotak0527" : {
            controller(){
                return {text:'yokotak0527'}
            },
            view(controller){
                return m('div',controller.text);
            }
        },
        "/user/:otherName" : {
            controller(){
                return {text:m.route.param('otherName')}
            },
            view(controller){
                return m('div',controller.text);
            }
        }
    }
);

デモ

上の例だと、遷移する可能性のあるラウトを3つ定義している

  • /user/ にアクセスすると1つ目のコンポーネントでレンダリング
  • /user/yokotak0527 にアクセスすると2つ目のコンポーネントでレンダリング
  • /user/xxxxx にアクセスすると3つ目のコンポーネントでレンダリング

/user/:otherName の 「:otherName」 はパラメータになる。
パラメータは m.route.param(text:String) で取得することが出来る。

以下のように可変長引数のように指定することも出来る。

...
"/user/:otherName..." : {
    controller(){
        return {text:m.route.param('otherName')}
    },
    view(controller){
        return m('div',controller.text);
    }
}
...

こうした場合、m.route.param(‘otherName’)の返り値は
「/?/user/aaa/bbb」にアクセスした場合、「aaa/bbb」になる。

クエリを渡した場合も m.route.param() で扱える。

またm.route.modeを利用することで、”?”や”#”などラウティングを定義するURLの種類を指定することが出来る。
※ デフォルトだと”?”
※ m.route() を使う前に設定すること。

m.route.mode = "search";

m.route.modeには以下の種類がある。

説明備考
search?を利用するIE8がhistory.pushStateをサポートしていないため、ページリフレッシュが発生する
hash#を利用する全てのブラウザで使えるが
topへ戻るなどのページ内リンクが利用できなくなる。
pathname特別な文字列を含まないブックマークとページリフレッシュをサポートするためには、サーバー側にも手を加える必要がる。
IE8は常にページリフレッシュされる。

m.routeには4つの使い方(4つの機能をオーバーライド)がある。

説明
m.route(rootElement, defaultRoute, routes)アプリケーションで使用できるURLとその時にロードされるコンポーネントの定義
m.route(path)他のラウトへリダイレクト
m.route()現在アクティブなラウトの取得
m.route(element)ラウトのモードを抽象化し、現在のモードで利用可能なエレメントの実リンクを取得

注意点:

m.route(path) は他のラウトへのリダイレクトなので、ラウトを定義せずにリダイレクトすることは出来ない。
そのようなことがしたい場合は、location.href を利用する。

m.request()

  • m.requestはAJAX通信などをする際に利用する。
  • リクエストが完了すると結果が格納されたm.propを返す。
    ※ m.propは直ぐに返されるが、中身が無い。リクエストが完了するまではundefinedになる。
  • 返されるm.propは通常のm.propと違いpromiseのインターフェイスを持っている(thenとか)
  • 成功時も失敗時もJSONエンコードが返ってくるとみなされる。(extractを使用することで回避出来る)
let users = m.prop('');
m.request({method : "GET", url : "http://httpbin.org/headers"}).then(users).then((_u)=>{
    console.log(_u);
    // Object{
        // headers...
    // }
});
// then(users)で返り値がusersに入る

// 別の例
var component = {
    model : {
        getHeader(){
            let param = {
                method : 'GET',
                url    : 'http://httpbin.org/delay/2' // 2秒後に結果が返ってくる
            }
            return m.request(param);
        }
    },
    controller(){
        return { data : component.model.getHeader() }
    },
    view(controller){
        // component.model.getHeaderの結果が帰ってきてから実行される
        let data = controller.data();
        return m('div',`IP:${data.origin}`);
    }
}

m.mount(document.body,component);

Mithrilのthennable(promise)の仕組みは以下の箇所、用途で使われることを想定している。

モデルレイヤ内ウェブサービスから受信したデータを変換処理をする場合。
例えばウェブサービス側でサポートしていないフィルタリングをクライアント側で行う場合など。
コントローラレイヤ内条件によって、リダイレクトするコードをバインドする場合や
エラーメッセージをバインドする場合。

thenは2つの引数を取る。第1引数は成功時、第2引数は失敗時

let request = m.request({
    method : 'GET',
    url    : 'http://httpbin.org/hidden-basic-auth/user/passwd'
});
request.then(
    ()=>{
        console.log('resolve');
    },
    (e)=>{
        console.log('reject');
    }
);
// -> reject

unwrapSuccess、unwrapErrorを使うことで返ってきたデータの一部だけを渡すなどのアンラップ作業を行うことができるようになる。

let = getHeader(){
    let param = {
        method        : 'GET',
        url           : 'http://httpbin.org/delay/2',
        unwrapSuccess : (response)=>{
            return response.headers;
        }
    }
    return m.request(param);
}

参考/引用サイト