Условные выражения в Hiccup, я могу сделать это более идиоматичным?
Clojure новичок здесь! Я добавил поддержку флеш-сообщений в мой код Hiccup в проекте Noir.
То, что я пытаюсь сделать, это проверить, была ли задана строка сообщения для каждого конкретного или нет. Если сообщения нет, я не хочу отображать конкретный флэш-элемент, содержащий это сообщение.
(defpartial success-flash [msg]
[:div.alert.notice.alert-success
[:a.close {:data-dismiss "alert"} "x"]
[:div#flash_notice msg]])
(defpartial error-flash [msg]
[:div.alert.notice.alert-error
[:a.close {:data-dismiss "alert"} "x"]
[:div#flash_notice msg]])
[..]
(defpartial layout [& content]
(html5
[:head
[...]
[:body
(list
[...]
[:div.container
(let [error-msg (session/flash-get :error-message)
error-div (if (nil? error-msg) () (error-flash error-msg))
success-msg (session/flash-get :success-message)
success-div (if (nil? success-msg) () (success-flash success-msg))]
warning-msg (session/flash-get :warning-message)
warning-div (if (nil? warning-msg) () (warning-flash warning-msg))]
(list error-div success-div warning-div content))])]))
Отказ от ответственности: я полностью согласен с тем, что вы вряд ли когда-либо окажетесь в ситуации, когда вам понадобится более одной из этих специальных вспышек одновременно, но побалуйте меня в моей попытке найти лучший и более функциональный способ реализации этого,
Я уверен, что есть способ справиться с подобными ситуациями. По сути, я проверяю значение нескольких выражений, делаю кучу вещей с этими значениями, а затем действую на основе результатов. Вы можете осуществить это все более и более чудовищно (cond), но мое решение, по крайней мере, несколько чище.
Подсказки?
2 ответа
Вы также можете использовать when-let
,
(defpartial layout
[& contents]
(html5
[:body
(when-let [msg (session/flash-get :error-message)]
(error-flash msg))
(when-let [msg (session/flash-get :warning-message)]
(warning-flash msg))
(when-let [msg (session/flash-get :success-message)]
(success-flash msg))
contents))
Я не эксперт по сбоям, но я думаю, что это должно сработать. Я нахожу это немного более ясным о том, что происходит, хотя это немного более многословно.
Шаблон называется значением отображения. Ниже приведен пример, который использует keep
функция для применения шаблона сопоставления значений, а затем их фильтрации
(use 'clojure.contrib.core)
(def flash-message
[[:error-message error-flash]
[:success-message success-flash]
[:warning-message warning-flash]])
(keep (fn [m f] (-?>> m (session/flash-get) (f))) flash-message)