В clojurescript, как оценить список - PullRequest
0 голосов
/ 16 мая 2018

Предположим, имея

(def defining-list `(def one 1))

Как я могу оценить список определения, чтобы один стал 1? (в закрытом тексте)

EDIT: Я дам представление о более широком изображении и о том, что я пытаюсь сделать здесь, чтобы не попасть в проблему X / Y.

Я пытаюсь использовать cljsjs / material-ui из пакета cljsjs Вместо того, чтобы каждый раз определять реагирующий компонент, чтобы использовать его следующим образом:

(def app-bar 
  (r/adapt-react-class (aget js/MaterialUI (name :AppBar)))

Я бы хотел определить все компоненты из массива тегов:

(def material-ui-tags '[AppBar Avatar Backdrop])

Так что я подумал, возможно ли это сделать без использования макроса, как я обнаружил this

Что-то вроде:

(doseq [component material-ui-tags]
  `(def ~(symbol (->kebab-case component)) (r/adapt-react-class (aget js/MaterialUI ~(name component)))))

Но приведенное выше создает только список определений, я хотел бы оценить их. В ближайшем будущем Эвал сделает свое дело.

1 Ответ

0 голосов
/ 17 мая 2018

С реагентом вы можете использовать :> как сокращение для adapt-react-class, как описано в https://github.com/reagent-project/reagent/blob/master/docs/InteropWithReact.md

Кроме того, вы можете использовать точечную запись с js/, и я думаю, что в shadow-cljs или cljs выше 1.9.854 вы можете require импортировать символ вместо использования aget.

В вашем случае это будет что-то вроде:

(ns example.core
  (:require [MaterialUI]))

(defn component-two []
  [:> MaterialUI/AppBar {:some-prop "some-value"}
    [:div "children-here"]])

(defn component-two []
  ;; If the require above doesn't work
  [:> js/MaterialUI.AppBar {:some-prop "some-value"}
    [:div "children-here"]])

Чтобы сделать то, что вы хотели, используя def, вам нужно либо eval, либо макрос. Эвал не идеален, как объяснил Джаред Смит в комментарии.

В примере, который вы связали с помощью reagent-material-ui, используется макрос. Вызов макроса фактически выполняет расширение, а затем оценку. Итак, ваш код должен быть примерно таким:

файл clj

(def material-ui-tags '[AppBar Avatar Backdrop])

(defmacro adapt-components []
  (for [component material-ui-tags]
    `(def ~(symbol (->kebab-case component)) (reagent.core/adapt-react-class (aget js/MaterialUI ~(name component))))))

файл cljs

(adapt-components) ;; your defs will be available below this line

(defn my-component []
  [app-bar ...])
...