descjop で遊ぼう day 10 : Om basedテンプレートにボタンをつけるその2

descjop (Electron + Clojure) Advent Calendar 2015 - Adventarの10日目です。

Story Permalink

続けてhelloworld_om_basedプロジェクトにボタンをつけて動的な処理をつけていきます。

前回の続きなので、今から読んだ方は前回のところまで作業を終えておいてください。

さて、ボタンを押すと、JavaScriptのアラートが出たのですが、まだそれだけです。

続いて、ボタンを押したら見出しが変わるようにしてみましょうか。

(js/alert "pressed!")は、一旦コメントアウトして、(om/transact! state :message (fn [] "World."))を追加します。

追加しおえたコードは、下記のとおりとなります。

(defn mount-root []
  (om/root
   (fn [state owner]
     (reify om/IRender
       (render [_]
         (dom/div nil
                  (dom/h1 nil (:message state))
                  (dom/button #js {:onClick (fn [e]
                                              ;; (js/alert "pressed!")
                                              (om/transact! state :message (fn [] "World.")))
                                   :className "press"}
                              "Hello")))))
   app-state
   {:target (. js/document
               (getElementById "app"))}))

transact!というのは、ざっくりと言うと、アプリケーションの状態を書き換える関数で、

(defn transact!
  ([cursor f] ...)
  ([cursor korks f] ...)
  ([cursor korks f tag]) ...)

こんな風に利用できることが、APIマニュアルに書かれています。

今回の使用例でいうと、

(om/transact! カーソル マップのキーワード 実行される関数)

という形で書いています。

ここで、カーソルという概念が出てきました。カーソルというのは、アプリケーション全体の状態のうち、コンポーネントが管理するべきアプリケーションの状態の一部です。

カーソルが活躍するのはコンポーネントを使ってアプリケーションを構築しはじめたときです。

現時点では、アプリケーションの状態くらいにとらえておいてよいでしょう。

Omでは、アプリケーションを作成する際に、アプリケーションの状態を管理するマップを用意して、それを渡すという状態の管理方法を使っています。

ここで、コード全体を見渡してみます。

(defonce app-state (atom {:message "Hello om world!"}))
 
(defn mount-root []
  (om/root
   (fn [state owner]
     (reify om/IRender
       (render [_]
         (dom/div nil
                  (dom/h1 nil (:message state))
                  (dom/button #js {:onClick (fn [e]
                                              ;; (js/alert "pressed!")
                                              (om/transact! state :message (fn [] "World.")))
                                   :className "press"}
                              "Hello")))))
   app-state
   {:target (. js/document
               (getElementById "app"))}))
 
(defn init! []
  (mount-root))

まず、(defonce app-state (atom {:message "Hello om world!"}))というところで、最初の状態を定義しています。

app-stateがアプリケーションの状態を指しているのです。

mount-root関数は今まで取り上げてきた通りですが、内容としてはom/rootを実行した結果を返します。

om/rootは、Omアプリケーションを作る際に必要なアプリケーションのルートで、実際にはコンポーネントなどを用意してそれらを組み合わせることでOmアプリケーションとして機能させます。

今回は直接OmアプリケーションのRoot内でいろいろやっていますが。

root関数は、こんな風に定義されており、

(defn root
  ([f value options] ...))

今回は、app-stateを第2引数に渡しています。

app-stateは、IRenderIRenderStateのインスタンスを返す関数として定義されるfに対して、ここではstateという名前で渡ってくるように定義しています。

それによって、(:message state)は、ここでは(:message @app-state)と同様の結果が得られるのです。

Omでは、アプリケーションの状態の変化に応じて、仮想DOMを自動で更新することができます。

例えば下記のようにコードを書き換えてみましょう。

(defn mount-root []
  (om/root
   (fn [state owner]
     (reify om/IRender
       (render [_]
         (dom/div nil
                  (dom/h1 nil (:message state))
                  (dom/p {:className "my-message"} (:message state))
                  (dom/button #js {:onClick (fn [e]
                                              ;; (js/alert "pressed!")
                                              (om/transact! state :message (fn [] "World.")))
                                   :className "press"}
                              "Hello")))))
   app-state
   {:target (. js/document
               (getElementById "app"))}))

h1の下にpタグを出力する(dom/p {:className "my-message"} (:message state))を置きました。

実行すると、ボタンを押した際にh1要素とp要素両方が変わっているのがわかるはずです。

Colophon

編集長
Greative GK. 原一浩 ( kara_d )
製版システム
Clojure / Compojure / Ring / Enlive / markdown-clj / Jetty / MySQL
Share this magazine!
Follow designudge

Magazine Archives

vol.122

2016-2-01

Cover

台湾に行ってきました。

今回のカバーは、台湾にて撮影したものです。

自治体Webデザイントレンドこぼれ話 : ここだよマップ

CSS Niteの年末イベントShiftでやっているセッションにデザイントレンドというのがあります。

descjop で遊ぼう day 16 : Windows版のメニューを表示する

2015年の振り返り的な一人レトロスペクティブ

そういえば、まだ2015年の振り返りをマガジンに掲載していませんでした

編集後記

vol.121

2016-1-14

Cover

今回のカバーは、、、UFO?

自治体Webデザイントレンドこぼれ話 : 予告

CSS Niteの年末イベントShiftでやっているセッションにデザイントレンドというのがあります。

descjop で遊ぼう day 11 : Omのコンポーネントで遊ぼう

descjop で遊ぼう day 12 : Omのコンポーネントで遊ぼうその2

descjop で遊ぼう day 13 : Clojure ワークショップでTAしてきた話

descjop で遊ぼう day 14 : アプリケーションメニューを作ろう

descjop で遊ぼう day 15 : descjop 0.5.3をリリースしました

編集後記

vol.120

2016-1-14

Cover

今回のカバーも、初詣に行ったときのショットです。

descjop で遊ぼう day 6 : Electronがうまくダウンロードできないとき

descjop で遊ぼう day 7 : Hello Worldを出力してみるには

descjop で遊ぼう day 8 : Om basedテンプレートを使ってみる

descjop で遊ぼう day 9 : Om basedテンプレートにボタンをつける

descjop で遊ぼう day 10 : Om basedテンプレートにボタンをつけるその2

編集後記

vol.119

2016-1-10

Cover

今回のカバーは、初詣に行ったときのショット。

「descjop で遊ぼう」について

「descjop で遊ぼう」というのは年末にやったアドベントカレンダーのシリーズなのですが、前段としてまずはその解説をば。

descjop で遊ぼう day 1 : はじめに

descjop で遊ぼう day 2 : 3つのテンプレート

descjop で遊ぼう day 3 : 環境構築をしよう

descjop で遊ぼう day 4 : Helpを見てみよう

descjop で遊ぼう day 5 : デフォルトアプリケーションのビルドと起動

編集後記

vol.118

2015-10-22

Cover

今回のカバーは、Stack Overflow DevDaysのイベントをお手伝いしたときの窓からのショット。

Vaqum Web Design Review

創刊以来延々と続くWebサイトレビュー

ミカヅキClojure : ゼロからはじめるClojure入門第2回

Clojureっていうじつに面白いプログラミング言語をとりあげていきます

インフォメーション

おすすめのイベント・勉強会情報を紹介

編集後記

vol.117

2015-10-07

Cover

今回は散歩道からのショット

Editor’s Picks

designudgeで扱っている内容に近いジャンルのリソースのうち気になったものなど

U.S. Web Design Standardsを見てみる

今話題となっているU.S. Web Design Standardsの周辺情報など見てみました

Bootstrap 4徹底攻略 (3)

Bootstrap 4のアルファ版がでているので使おう

インフォメーション

おすすめのイベント・勉強会情報を紹介

編集後記

vol.116

2015-9-28

Cover

今回は帰省した際に通った三島からのショットです

Vaqum Web Design Review

創刊以来延々と続くWebサイトレビュー

みそじ過ぎからの英語再学習

40を目前に今までサボっていた英語学習をはじめました

Bootstrap 4徹底攻略 (2)

Bootstrap 4のアルファ版がでているので使おう

ミカヅキClojure

Clojureっていうじつに面白いプログラミング言語をとりあげていきます

インフォメーション

おすすめのイベント・勉強会情報を紹介

編集後記

vol.115

2015-9-13

Cover

前回と同じ開発合宿のショットから一つ

Vaqum Web Design Review

創刊以来延々と続くWebサイトレビュー

開発合宿へ行こう! : Python mini hack-a-thon 夏山合宿 2015

先週末に行ってきた開発合宿について書きました。

ミカヅキClojure

Clojureっていうじつに面白いプログラミング言語をとりあげていきます

インフォメーション

おすすめのイベント・勉強会情報を紹介

編集後記