読者です 読者をやめる 読者になる 読者になる

レガシーコード生産ガイド

私に教えられることなら

Secretaryで#無しのURLを扱う

Secretaryのサンプルコードこんなカンジになってるんだけど

(ns hoge.client
  (:require [secretary.core :as secretary :refer-macros [defroute]]
            [goog.events :as events]
            [goog.history.EventType :as EventType])
  (:import goog.History))

(enable-console-print!)

(defroute "/" []
  (println "root!"))

(defroute "/login" []
  (println "login!"))

(secretary/set-config! :prefix "#")

;; History Configuration
(let [h (History.)]
  (goog.events/listen h EventType/NAVIGATE
                      (fn [token]
                        (secretary/dispatch! (.-token token))))
  (doto h
    (.setEnabled true)))

Html5のHistory?に対応してるブラウザは自動的に#無しのURLでアクセスしても同じようにルーティングしてくれるかと思ったんだけど、そうでもなかった。つまり/loginにアクセスしてもroot!と表示される。/#/loginならlogin!と表示された。

解決

goog.Historyの代わりにgoog.history.Html5Historyを使い、いくつか設定してやる。

(ns hoge.client
  (:require [secretary.core :as secretary :refer-macros [defroute]]
            [goog.events :as events]
            [goog.history.EventType :as EventType])
  (:import goog.history.Html5History)) ; 変更

(enable-console-print!)

(defroute "/" []
  (println "root!"))

(defroute "/login" []
  (println "login!"))

(secretary/set-config! :prefix "#")

;; History Configuration
(let [h (Html5History.)] ; 変更
  (goog.events/listen h EventType/NAVIGATE
                      (fn [token]
                        (secretary/dispatch! (.-token token))))
  (doto h
    (.setPathPrefix "") ; 追加
    (.setUseFragment false) ; 追加
    (.setEnabled true))) ; 追加した上2つより後である必要がある

これで/loginにアクセスするとlogin!と表示された。しかし今度は/#/loginを認識できなくなってしまった。Html5 Historyに対応してないブラウザだと使えないんだろうか?サポート状況を見るとAndroidブラウザ4.1で対応してないのが気になるな。

広告を非表示にする