Mithril 1.1.0

withAttr(attrName, callback)


説明

特定のDOM属性の値を取得してcallbackを呼ぶためのイベントハンドラーを生成します。

var state = {
    value: "",
    setValue: function(v) {state.value = v}
}

var Component = {
    view: function() {
        return m("input", {
            oninput: m.withAttr("value", state.setValue),
            value: state.value,
        })
    }
}

m.mount(document.body, Component)

シグニチャ

m.withAttr(attrName, callback, thisArg?)

引数 必須 説明
attrName String Yes 値を取得したい属性やプロパティの名前
callback any -> undefined Yes コールバック
thisArg any No コールバック関数内のthisキーワードに束縛したい値
返り値 Event -> undefined イベントハンドラ関数

シグニチャの読み方


どのように動作するのか

m.withAttrメソッドはイベントハンドラを作成します。イベントハンドラはDOMエレメントのプロパティ値を読み取り、コールバック関数の引数としてその値を渡して実行します。

このヘルパー関数を使うと、ブラウザのイベントモデルとアプリケーションコードの密結合を緩めることができます。

// 単体の使用例
document.body.onclick = m.withAttr("title", function(value) {
    console.log(value) // <body>要素をクリックした時にタイトルをログ出力
})

通常、m.withAttr()はMithrilコンポーネントのビューで使い、DOMイベントモデルのデータ構造のレイヤーとビューを分離するのに使います:

var state = {
    email: "",
    setEmail: function(email) {
        state.email = email.toLowerCase()
    }
}

var MyComponent = {
    view: function() {
        return m("input", {
            oninput: m.withAttr("value", state.setEmail),
            value: state.email
        })
    }
}

m.mount(document.body, MyComponent)

述語イベントターゲット

m.withAttr()はイベントハンドラに束縛されたエレメントの値を取得するため、生成されたイベントとエレメントが同じ必要はありません。

var state = {
    url: "",
    setURL: function(url) {state.url = url}
}

var MyComponent = {
    view: function() {
        return m("a[href='/foo']", {onclick: m.withAttr("href", state.setURL)}, [
            m("span", state.url)
        ])
    }
}

m.mount(document.body, MyComponent)

このサンプルではリンクのテキストをクリックした時にコールバックが呼ばれますが、e.targetが指すタグは<span><a>ではありません。

この動作は仕様通りですが、直感的ではないでしょう。そのため、m.withAttre.currentTargetの値を使います。これは多くの人が期待する<a>を参照します。


属性とプロパティ

m.withAttr()の最初の引数は属性でもプロパティでも使用できます。

// `select.selectedIndex` プロパティの取得
var state = {
    index: 0,
    setIndex: function(index) {state.index = index}
}
m("select", {onclick: m.withAttr("selectedIndex", state.setIndex)})

値が属性かつプロパティだった時はプロパティの値が使用されます。

// `input.checked` プロパティがbooleanなので、値もboolean
var state = {
    selected: false,
    setSelected: function(selected) {state.selected = selected}
}
m("input[type=checkbox]", {onclick: m.withAttr("checked", state.setSelected)})

License: MIT. © Leo Horie.