我已经爬过了一些......"。网络 和 视频 路由的文档。但我无法让动态UI路由在一组简单的页面上工作。
root.cljs
(ns ui.root)
;; ...
(defsc Index [this props]
{:query [:index]
:ident (fn [] [:id :index])
:route-segment ["index"]
:initial-state {}}
(h3 "Index"))
(defsc Landing [this props]
{:query [:landing]
:ident (fn [] [:id :landing])
:route-segment ["landing"]
:initial-state {}}
(h3 "Landing"))
(defsc Settings [this props]
{:query [:settings]
:ident (fn [] [:id :settings])
:route-segment ["settings"]
:initial-state {}}
(h3 "Setting"))
(dr/defrouter TopRouter [this {:keys [current-state] :as props}]
{:router-targets [Game Settings Landing Index]
:initial-state (fn [{:keys [current-state]}]
{:current-state current-state})}
(case current-state
:pending (dom/div "Loading...")
:failed (dom/div "Failed!")
(dom/div "No route selected.")))
(def ui-top-router (comp/factory TopRouter))
(defsc Root [this {:keys [router] :as props}]
{:query [{:router (comp/get-query TopRouter)}]
:ident (fn [] [:id :root])
:initial-state (fn [_]
{:top-router (comp/get-initial-state TopRouter {:current-state :pending})
:index {:id 1}
:landing {:id 1}
:settings {:id 1}})
:componentDidMount (fn [_] (log/info "Root Initial State /" (prim/get-initial-state Root {})))}
(log/info "Root Props /" this props)
(ui-top-router router {:current-state :pending}))
client.cljs
(ns client)
...
(app/mount! @app root/Root "app" {:initialize-state? true
:foo :bar})
问:初始加载时给出了这样的输出。我们如何将props传递到Root组件中?我希望至少能看到 {:foo :bar}
.
INFO [ui.root:81] - Root Props / [object Object] {}
INFO [ui.root:53] - TopRouter Props / {:current-state nil, :route-factory #object[cljs.core.MetaFn], :pending-path-segment nil, :route-props nil}
INFO [ui.root:77] - Root Initial State / nil
问:如果这是我的初始状态,是否是 :query
和 :ident
对吗?它们(:query + :ident)是否对应于 :route-segment
? 他们需要吗?
{:index {:id 1}
:landing {:id 1}
:settings {:id 1}}
问:如何启动初始路线?调用此功能失败,出现以下信息。
(dr/change-route app ["index"])
INFO [com.fulcrologic.fulcro.rendering.ident-optimized-render:146] - Optimized render failed. Falling back to root render.
>> UPDATE <<
我能够得到一个有效的Fulcro Root。:initial-state
和 :query
和 :ident
子组件上。
在初始加载时,路由器会出现这样的故障。
INFO [beatthemarket.ui.root:61] - TopRouter Props / {:current-state nil, :route-factory #object[cljs.core.MetaFn], :pending-path-segment nil, :route-props {:index/id 1, :index/text "Index Text"}}
core.cljs:159 ERROR [com.fulcrologic.fulcro.routing.dynamic-routing:410] - will-enter for router target beatthemarket.ui.root/Index did not return a valid ident. Instead it returned: [:index/id nil]
core.cljs:159 ERROR [com.fulcrologic.fulcro.routing.dynamic-routing:410] - will-enter for router target beatthemarket.ui.root/Index did not return a valid ident. Instead it returned: [:index/id nil]
browser.cljs:25 shadow-cljs: WebSocket connected!
browser.cljs:25 shadow-cljs: REPL session start successful
core.cljs:159 INFO [com.fulcrologic.fulcro.algorithms.indexing:104] - component beatthemarket.ui.root/Index's ident ([:index/id nil]) has a `nil` second element. This warning can be safely ignored if that is intended.
所以像这样的命令 (dr/change-route app (dr/path-to root/Index))
失败与此。
react_devtools_backend.js:6 ERROR [com.fulcrologic.fulcro.routing.dynamic-routing:410] - will-enter for router target beatthemarket.ui.root/Index did not return a valid ident. Instead it returned: [:index/id nil]
这些是我的 client.cljs 和 root.cljs 看起来像这样。
我想你首先要解决Index组件的Ident问题。
其他组件的路由是否有效?
我认为你的Root初始状态应该是调用 (comp/get-initial-state Index)
. 你在Index上设置了一个初始状态,但它与Root给出的初始状态不同。
另外,Fulcro(和React)的一个重要部分是,你建立了一个组件树和数据树,它们需要匹配。
你这里的方式,"Root "和 "Index "之间没有任何联系,因为Root只渲染了 (ui-top-router router)
. 你通过查询Index的数据来获取 {:root/index (comp/get-query Index)}
但你并没有通过让Root调用Index并传入数据来创建Root和Index之间的连接。你需要一个 (ui-index index)
根里面。
如果你这样做,那么在那个 (ui-index index)
呼叫。index
将会取你正在用 :initial-state
. 这就是为什么你还需要更新初始状态来调用 comp/get-initial-state
这样你就可以得到 :index/id 1
值,你在Index组件的初始状态中设置的。
(defsc Index [this {:index/keys [id text]}]
{:query [:index/id :index/text]
:ident [:index/id :index/id]
:route-segment ["index"]
:initial-state {:index/id 1
:index/text :param/text}}
(h3 text))
(defsc Root [this {:root/keys [router index landing game settings]}]
{:query [{:root/router (comp/get-query TopRouter)}
{:root/index (comp/get-query Index)}
{:root/landing (comp/get-query Landing)}
{:root/game (comp/get-query Game)}
{:root/settings (comp/get-query Settings)}]
:initial-state {:root/router {}
:root/index {:text "Index Text"}
:root/landing {:text "Landing Text"}
:root/game {:text "Game Text"}
:root/settings {:text "Settings Text"}}}
(when router
(dom/div (ui-top-router router))))
在解决了所有这些问题之后,接下来就是你可能感兴趣的事情了。
你可能并不总是想要硬编码的 index/id 1
. 你可能需要从服务器上获取数据,以便有任何东西来渲染。
这时 :will-enter
和 "递延路由 "发挥作用。请看下面的例子和文档 http:/book.fulcrologic.com#_router_rendering_of_deferred_ui。.
(defsc Person [this {:ui/keys [modified?]
:person/keys [id name]
:address/keys [city state]
:as props}]
{:query [:ui/modified? :person/id :person/name :address/city :address/state]
:ident :person/id
:route-segment ["person" :person/id]
:route-cancelled (fn [{:person/keys [id]}]
(log/info "Routing cancelled to user " id))
:allow-route-change? (fn [this {:ui/keys [modified?]}]
(when modified?
#?(:cljs (js/alert "You cannot navigate until the user is not modified!")))
(not modified?))
:will-enter (fn [app {:person/keys [id] :as route-params}]
(log/info "Will enter user with route params " route-params)
;; be sure to convert strings to int for this case
(let [id (if (string? id) (edn/read-string id) id)]
(dr/route-deferred [:person/id id]
#(df/load app [:person/id id] Person
{:post-mutation `dr/target-ready
:post-mutation-params {:target [:person/id id]}}))))}