3

Clojure初学者在这里!我在 Noir 项目中为我的 Hiccup 代码添加了 Flash 消息支持。

我要做的是检查是否设置了每个特定的消息字符串。如果没有消息,那么我不想显示包含该消息的特定 flash 元素。

(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)来解决这个问题,但我的解决方案至少更干净一些。

提示?

4

2 回答 2

5

你也可以使用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))

我不是打嗝专家,但我认为这应该可行。我发现它对正在发生的事情更清楚一点,尽管它稍微冗长一些。

于 2012-08-14T14:27:07.230 回答
4

该模式称为映射值。下面是一个使用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)
于 2012-08-14T08:44:43.777 回答