iPhoneで Grafanaの グラフを 参照できる アプリ Grafanizer 作ってます。 詳しくは こちらへ

参考になるサンプルを Mithril.js Ver.0.2.5 で動くように修正し、ついでにコードをシンプルに調整してみました。

参考にしたページ

指定したElementへMithrilを使って表示


var azucic = m("div", "hogehoge.");
m.render(document.getElementById("azucic"), azucic);

styleを指定して表示


var style = { "font-style": "italic" };
var butamih = m("div", {style: style}, "hogehoge.");
m.render(document.getElementById("butamih"), butamih);

config を使って表示後に指定した処理を実行


function sourceCopy(element) {
  document.getElementById("vuzmofi-copy").innerHTML = element.innerHTML + "(copy from vuzmofi)";
}
m.render(document.getElementById("vuzmofi"), m("div", { config: sourceCopy }, "hogehoge."));

map を使ってリスト表示


var links = [
  {title: "apple", url: "http://www.apple.com"},
  {title: "google", url: "http://www.google.com"}
];
m.render(document.getElementById("abavo"), [
  m("ul",
    links.map(function(link) {
      return m("li",
        m("a", {href: link.url}, link.title)
      );
    })
  )
]);

Viewを作って指定したElementへ表示


var efiera = {
  view: function() {
    return m("div", "hogehoge.");
  }
};
m.mount(document.getElementById("efiera"), efiera);

変数を作って自動的にその値に書き換え


var ifeha = {
  count: 0,
  stab: function() {
    this.count++;
  },
  view: function() {
    return m("button.button.is-primary",
             {onclick: this.stab.bind(this)},
            "このボタンは " + this.count + " 回クリックされました。");
  }
};
m.mount(document.getElementById("ifeha"), ifeha);

Attributeを引数に関数を実行できる m.withAttr() のサンプル


var azwofnu = {
  view: function() {
    return [
      m("div.control.has-addons", [
        m(
          "a.button",
          { onclick: m.withAttr("className", function(m) { alert(m); }) },
          "このボタンのクラスは?"
        ),
        m(
          "a.button",
          { onclick: m.withAttr("tagName", function(m) { alert(m); }) },
          "このボタンのタグは?"
        ),
        m(
          "button.button",
          { onclick: m.withAttr("tagName", function(m) { alert(m); }) },
          "このボタンのタグは?"
        )
      ]),
      m("div", [
        m(
          "input[type=text].input",
          {
            value: "カーソルを合わせると内容をアラート表示",
            onclick: m.withAttr("value", function(m) { alert(m); })
          }
        )
      ])
    ];
  }
};
m.mount(document.getElementById("azwofnu"), azwofnu);

変数に自動的にgetter/setterが作成される m.prop() のサンプル


var dejgikuf = {
  text: m.prop(),
  alert: function() {
    var message = (this.text() == undefined)?
      "何も入力されていません":
      "\"" + this.text() + "\" が入力されています。";
    alert(message);
  },
  view: function() {
    return m("div.control.has-addons", [
      m(
        "input[type=text].input",
        {
           onchange: m.withAttr("value", this.text),
           placeholder: "input here..."
         }
      ),
      m(
        "button.button.is-primary.input-group-btn",
        { onclick: this.alert.bind(this) },
        "Alert"
      )
    ]);
  }
}
m.mount(document.getElementById("dejgikuf"), dejgikuf);

Ajaxでデータを取得する m.request() のサンプル


var azpek = {
  data: m.prop(false),
  url: "http://ratfactor.com/misc/lotr-fellowship.json.php",
  click: function() {
    m.request({
      method: "GET",
      url: this.url
    }).then(this.data);
  },
  view: function() {
    return this.data()?
        m("p", this.data().description):
        m("button.button.is-primary", { onclick: this.click.bind(this) }, "Load RSS");
  }
}
m.mount(document.getElementById("azpek"), azpek);

m.route() を使ってブックマークできるSPAのサンプル


var menu = {
  view: function() {
    return m("div.btn-group", [
      btn("Page1", "/page1"),
      btn("page2", "/page2")
    ]);
    function btn(name, route) {
      var isCurrent = (m.route() === route);
      var click = function() { m.route(route); };
      return m(
        "button.button"+(isCurrent? ".is-primary": ""),
        {onclick: click},
        name
      );
    }
  }
}

function Page(content, id) {
  this.view = function() {
    return [menu.view(), m("div.divider"), m(".page", m("p", content))];
  }
}

var page1 = new Page("This is page1");
var page2 = new Page("This is page2");

// m.route.mode = "hash";
m.route(document.getElementById("cehofga"), "/page1", {
  "/page1": page1,
  "/page2": page2
});

controller を利用したサンプル


var besiiw = {
  controller: function() { this.value = "hogehoge."; },
  view: function(ctl) { return m("div", "Value is " + ctl.value); }
}
m.mount(document.getElementById("besiiw"), besiiw);

ViewModelをつかった controller のサンプル


var gagsestoj = {
  vm: {
    value: "hogehoge.",
    echo: function() { return [0, 1].map(function(d) { return gagsestoj.vm.value; }).join(" ")},
    clicked: false,
    click: function() { this.clicked = true; }
  },
  controller: function() { this.vm = gagsestoj.vm; },
  view: function(ctrl) {
    return [
      m("div", ctrl.vm.value),
      m("button.button.is-primary", { onclick: function() { ctrl.vm.click(); } }, "echo"),
      m("div", ctrl.vm.clicked? ctrl.vm.echo(): "")
    ];
  }
};
m.mount(document.getElementById("gagsestoj"), gagsestoj);

Model, ViewModelを使い外部タイマーでの表示切替


// Modelを準備
// Modelは複数のコンポーネントから利用される可能性があるので外出しにする
var model = ["Eddie Benson", "Kenneth Wilson", "Tillie Barrett", "Curtis Gomez", "Russell Mitchell"];

// コンポーネントの作成
var caneti = {

  // Viewで表示したり、Viewから書き込んだりするするViewModel
  // もしModelを差し替えたくなったときはここでModelを切り替えるだけで済む
  vm: {
    names: model,
    name: m.prop(),
    value: m.prop()
  },

  // Viewからは全てCtrl経由でアクセスし、ModelへはViewModel経由でアクセス
  controller: function() {
    var self = this;
    return {
      vm: caneti.vm,
      addName: function() {
        caneti.vm.names.push(caneti.vm.value());
      }
    };
  },

  view: function(ctrl) {
    return  [
      m("div", "names: [" + ctrl.vm.names.join(", ") + "]"),
      m("div.control.has-addons", [
        m(
          "input[type=text].input",
          {
            onchange: m.withAttr("value", ctrl.vm.value),
            placeholder: "input here..."
          }
        ),
        m("button.button.is-primary.input-group-btn", {onclick: ctrl.addName}, "add name")
      ]),
      m("div", "random name: " + ctrl.vm.name())
    ];
  }
};

// HTML表示
m.mount(document.getElementById("caneti"), caneti);

// 1sec毎にランダムに名前を表示
setInterval(function() {

  // Mithrilにデータの変更開始を通知
  m.startComputation();

  // VMの名前を直接書き換え
  var random = Math.floor(Math.random() * (model.length));
  caneti.vm.name(model[random]);

  // Mithrilにデータの変更完了を通知
  m.endComputation();

}, 1000);