2015-07-23 2 views
4

Прежде всего, этот https://github.com/taylorSando/om-material-ui не работает с последним интерфейсом React/Material. Основная причина, я думаю, это предупреждение в консоли:Как создать компонент пользовательского интерфейса в Om Clojurescript?

Warning: Something is calling a React component directly. Use a factory or JSX instead. See: https://fb.me/react-legacyfactory

Я также пытался создать компонент «вручную»:

(ns om-test.core 
    (:require [om.core :as om :include-macros true] 
      [om-tools.dom :as dom :include-macros true] 
      [om-tools.core :refer-macros [defcomponent]] 
      [om-material-ui.core :as mui :include-macros true])) 

(enable-console-print!) 

(defonce app-state (atom {:text "Hello Chestnut!"})) 

(defn main [] 
    (om/root 
    (fn [app owner] 
     (reify 
     om/IRender 
     (render [_] 
      (dom/div (dom/element js/MaterialUI.Paper {} "Hello") 
        (mui/paper {} "Hello")) 
     ))) 
    app-state 
    {:target (. js/document (getElementById "app"))})) 

Таким образом, оба этих подхода производит то же самое предупреждение выше.

В React были некоторые изменения. Он предлагает создать компоненты программно как:

var React = require('react'); 
var MyComponent = React.createFactory(require('MyComponent')); 

function render() { 
    return MyComponent({ foo: 'bar' }); 
} 

Так как создать компонент материала UI внутри Om функции визуализации, или, может быть, лучше Как создать Реагировать функцию компонента внутри Ом визуализации, в общем?

По материалу UI я имею в виду это https://github.com/callemall/material-ui

Мои зависимости

:dependencies [[org.clojure/clojure "1.6.0"] 
       [org.clojure/clojurescript "0.0-3058" :scope "provided"] 
       [ring "1.3.2"] 
       [ring/ring-defaults "0.1.4"] 
       [compojure "1.3.2"] 
       [enlive "1.1.6"] 
       [org.omcljs/om "0.9.0"] 
       [environ "1.0.0"] 
       [http-kit "2.1.19"] 
       [prismatic/om-tools "0.3.11"] 
       [om-material-ui "0.1.1" :exclusions [org.clojure/clojurescript 
                 org.clojure/clojure]]] 

ответ

6

Хорошо, я в конце концов понял.

  1. Построить последнюю версию пользовательского интерфейса с материалом: https://github.com/taylorSando/om-material-ui/tree/master/build-mui. Примечание: нет необходимости создавать CSS в текущей версии (0.10.4)
  2. Включите построенный material.js в свой HTML-файл. Опять же, нет необходимости включать CSS.
  3. Избегайте загрузки Реагировать дважды https://github.com/taylorSando/om-material-ui#avoid-loading-react-twice

Теперь код для Ом:

(ns material-ui-test.core 
    (:require [om.core :as om :include-macros true] 
      [om.dom :as dom :include-macros true])) 

(enable-console-print!) 

(defonce app-state (atom {:text "Hello Chestnut!"})) 

(def ^:dynamic *mui-theme* 
    (.getCurrentTheme (js/MaterialUI.Styles.ThemeManager.))) 

(defn main [] 
    (om/root 
    (fn [app owner] 
     (reify 
     om/IRender 
     (render [_] 
      (let [ctor (js/React.createFactory 
         (js/React.createClass 
         #js 
          {:getDisplayName (fn [] "muiroot-context") 
           :childContextTypes #js {:muiTheme js/React.PropTypes.object} 
           :getChildContext (fn [] #js {:muiTheme *mui-theme*}) 
           :render   (fn [] 
                (dom/div nil 
                  (dom/h1 nil (:text app)) 
                  (js/React.createElement js/MaterialUI.Slider)))}))] 
      (ctor. nil))))) 
    app-state 
    {:target (. js/document (getElementById "app"))})) 

Если вы использовали только (js/React.createElement js/MaterialUI.Slider) без :getChildContext и т.д. было бы бросить ошибку:

Uncaught TypeError: Cannot read property 'component' of undefined

Th происходит из-за того, как работает текущий MaterialUI. Прочтите раздел «Использование» здесь: http://material-ui.com/#/customization/themes

Код для Реагент более изящный.Но я использовал здесь пространство имен

[material-ui.core :as ui :include-macros true]

копию вставила из этого примера проекта: https://github.com/tuhlmann/reagent-material

(def ^:dynamic *mui-theme* 
    (.getCurrentTheme (js/MaterialUI.Styles.ThemeManager.))) 

(defn main-panel [] 
    (let [active-panel (rf/subscribe [:active-panel])] 
    (r/create-class 
     {:display-name "Main Panel" 

     :child-context-types 
        #js {:muiTheme js/React.PropTypes.object} 

     :get-child-context 
        (fn [this] 
         #js {:muiTheme *mui-theme*}) 
     :reagent-render 
        (fn [] 
         [ui/Slider {:name "slide1"}])}))) 

EDIT: я выпустил библиотеку, что значительно упрощает весь процесс.

Библиотека: https://github.com/madvas/cljs-react-material-ui

Пример приложения: https://github.com/madvas/cljs-react-material-ui-example

0

Я не использую материал UI, но React Widgets. Вот wrapper мне нужно писать для ОМ:

(defn dropdown-list 
    [data owner {:keys [val-key menu-key id-key label-key props]}] 
    (reify 
    om/IRender 
    (render [_] 
     (let [menu (-get data menu-key)] 
     (js/React.createElement js/ReactWidgets.DropdownList 
      (-> {:defaultValue (-> (find-by-key menu id-key (-get data  val-key)) 
           (-get label-key)) 
       :data (mapv #(-get % label-key) menu) 
       :onChange (fn [new-val] 
          (let [new-id (-> (find-by-key menu label- key new-val) 
              (-get id-key))] 
          (om/update! data val-key new-id)))} 
      (merge props) 
      clj->js)))))) 

Так, в общем, вы должны получить класс React (js/ReactWidgets.DropdownList) и вызвать js/Readt.createElement при прохождении реквизита на render.

Смежные вопросы