首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确地将Google Closure UI组件包装为Rum组件

如何正确地将Google Closure UI组件包装为Rum组件
EN

Stack Overflow用户
提问于 2017-04-25 07:42:31
回答 1查看 416关注 0票数 2

我想使用来自ClojureScript的Google Closure UI组件和Rum/React库。

我开始使用goog.ui.DatePicker,但仍然不能正确包装它。下面的代码在组件挂载和正确的位置呈现DatePicker一次,事件侦听器工作,一切都很好,除了它需要在dom节点上静态设置的id ("here")工作,这对于一次hack是可以接受的,但当我需要将组件包装并在同一个页面/应用程序上多次使用时就不是这样了。

代码语言:javascript
复制
(ns redux.components
  (:require [rum.core :as r]
            [cljs-time.core :as time]
            [cljs-time.format :as tf]
            [goog.dom :as dom]
            [goog.ui.DatePicker :as goog-picker]
            [goog.events :as goog-events]]))

   (r/defcs +published-at < { :did-mount (fn [state]
                   (let [target-node  (:r/ref state "here")
                         dp (goog.ui.DatePicker. nil goog.i18n.DateTimeSymbols_cs)]
                   (.listen dp (.. goog.ui.DatePicker -Events -CHANGE) #(println "new date is: " (tf/unparse (tf/formatter "YYYY-MM-dd")(time/to-default-time-zone (.. % -target getDate)))))
                   (.render dp (goog.dom/getElement "here")))
                   state) }
        []
        [:div#here])

   (r/defc app
        []
        [:div
           [:h1 "title"
              (+published-at)]])

我进一步不成功的研究

React documentation suggests认为,为了与第三方DOM库集成,可能需要ref。朗姆documentation describes如何做来自朗姆酒的反应参考。但问题是,React文档声明字符串ref是遗留的,可能会在未来的版本中删除,而Rum文档不包括基于回调的ref。我试图猜测如何将两个框架与字符串引用和回调引用结合在一起,但似乎两者都不起作用:

基于字符串的遗留方法

代码语言:javascript
复制
(r/defcs +published-at < { :did-mount (fn [state]
               (let [target-node  (:r/ref state "here")
                     dp (goog.ui.DatePicker. nil goog.i18n.DateTimeSymbols_cs)]
               (.listen dp (.. goog.ui.DatePicker -Events -CHANGE) #(println (tf/unparse (tf/formatter "YYYY-MM-dd")(time/to-default-time-zone (.. % -target getDate)))))
               (.render dp target-node))
               state) }
     []
     [:div
      [:div { :ref "here" } ]])

此操作失败并出现错误,甚至不显示DatePicker:

代码语言:javascript
复制
Uncaught TypeError: opt_parentElement.insertBefore is not a function
    at goog.ui.DatePicker.goog.ui.Component.render_ (component.js:705)
    at goog.ui.DatePicker.goog.ui.Component.render (component.js:659)
    at Function.<anonymous> (components.cljs?rel=1493075625598:123)
    at Function.cljs.core.apply.cljs$core$IFn$_invoke$arity$3 (core.cljs:3694)
    at cljs$core$apply (core.cljs:3676)
    at util.cljc?rel=1492772300984:17
    at core.cljs:2314
    at Function.cljs.core.seq_reduce.cljs$core$IFn$_invoke$arity$3 (core.cljs:2314)
    at cljs.core.LazySeq.cljs$core$IReduce$_reduce$arity$3 (core.cljs:3287)
    at Function.cljs.core.reduce.cljs$core$IFn$_invoke$arity$3 (core.cljs:2358)

基于回调的方法

代码语言:javascript
复制
(r/defcs +published-at < { :did-mount (fn [state]
               (let [dp (goog.ui.DatePicker. nil goog.i18n.DateTimeSymbols_cs)]
               (.listen dp (.. goog.ui.DatePicker -Events -CHANGE) #(println (tf/unparse (tf/formatter "YYYY-MM-dd")(time/to-default-time-zone (.. % -target getDate)))))
               (.render dp (::put-date-here state)))
               state) }
     [state]
     [:div
      [:div { :ref #(assoc state ::put-date-here %) }]])

这将在页面末尾呈现functional DatePicker,但不在组件中。

EN

回答 1

Stack Overflow用户

发布于 2017-04-29 14:17:54

这里不需要:did-mount,只需在回调中呈现它即可。这对我来说很好:

代码语言:javascript
复制
(defn show-datepicker
  [d]
  (let [dp (goog.ui.DatePicker. nil goog.i18n.DateTimeSymbols_cs)]
    (.listen dp (.. goog.ui.DatePicker -Events -CHANGE)
             #(js/console.info
                (.. % -target getDate)))
    (.render dp d)))


[:div {:ref show-datepicker}]

如果您需要拆除datepicker,那么只需检查show-datepicker中的(nil? d)即可。当组件卸载时,React将传递nil。

PS:我不会使用cljs-time,除非你真的喜欢大的js输出文件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43599310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档