2014-05-19 6 views
3

ClojureScript에서 순환 종속성으로 고민하고 있습니다. 나는 한 달 동안이 언어를 사용해 본 적이 있고, 진짜 물건으로 일한 적이 없다 (Clojure).ClojureScript 순환 종속성

라우터로 secretary을 사용하는 클라이언트 측 앱이 있습니다. 내 경로를 정의 할 때는 핸들러 함수이며 history-channel에 값을 푸시합니다.이 값은 특정보기를 표시하는 기본 앱 구성 요소에 의해 소비됩니다. 따라서 내 경로에서 푸시 한 값에는 view 함수에 대한 참조가 포함되어 있습니다. 이 뷰 함수는 주어진 위치를 렌더링하는 om 구성 요소입니다. 이 뷰 기능에서는 종종 앱의 다른 위치에 대한 링크, URL을 생성해야합니다. 이러한 URL은이를 참조하는 핸들러 함수에서 생성됩니다. 내 순환 의존성이 어떻게 생겨 났는가. 그것을 해결하는 우아한 방법은 무엇입니까?

router -> views -> router 

- route.cljs

(ns myapp.route 
    (:require [secretary.core :as secretary :include-macros true :refer [defroute]] 
      [myapp.views.welcome :as welcome] 
      [myapp.views.some :as some])) 

(defroute home "/" {} 
    (put! history-chan {:token "/" 
         :view welcome/view})) 

(defroute some "/some" {} 
    (put! history-chan {:token "/some" 
         :view some/view})) 

- 난 어떤 URL을 생성/경로를 사용하지 않는,

나는 그런 문제가 있었
(ns myapp.views.welcome 
    (:require [om.core :as om :include-macros true] 
      [sablono.core :as html :refer-macros [html]] 
      [myapp.route :as route])) 

(defn view [state owner] 
    (reify 
    om/IRender 
    (render [_] 
     (html [:div [:a {:href (route/some)}]])))) 
+1

모든 것을 하나의 파일로 옮깁니다 :-) – edbond

+0

불행히도 Clojure의 순환 종속성에 대한 쉬운 대답은 없습니다. 가장 좋은 방법은 리팩터링하는 것입니다. 한 방향으로 의존성을 제거하기 위해 코드를 다시 작성하십시오. –

+0

감사합니다. @ErikKronberg이 특별한 경우를 리팩터링하는 방법에 대한 예를 들어 주시면 감사하겠습니다. 그것은 매우 도움이 될 것입니다. – skrat

답변

0

을 welcome.cljs. 라우터를 필요로하지 않습니다

 [react.nav :as nav] 
     [react.loading :as loading] 
     [react.alerts :as alerts] 
........ 
(def history (History.)) 

(events/listen 
history (.-NAVIGATE goog.history.EventType) 
(fn [e] 
    (secretary/dispatch! (.-token e)))) 

(defroute "alerts" {:as params} 
    (nav/switch-to "Alerts") 
    (alerts/display)) 

조회수 :

라우터 (history.cljs)은 모든보기를 포함한다. 링크는 다음과 같이 작동합니다 : Clojure의에서 (str "alerts/" sort-key "/" filter-str)

HTH

+0

맞아요.하지만'setToken'을 호출 할 때 문자열을 복제하고 싶지 않습니다. 비서가 그것을 생성하기를 원합니다. DRY :'defroute'에서 경로를 변경할 때, 나는 그 문자열을 사용했던 곳에서 뷰와 추측 (grep)을 할 필요가 없습니다. – skrat

+0

좋은 지적이지만 대답이 정확하지 않습니다. – edbond

2

순환 종속성이 더 쉽거나 우아한 해결책이 없다 :

(def history (History.)) 
    ..... 
      :on-click (fn [e] 
      (.preventDefault e) 
      (.setToken history link))} 

당신은 당신이 필요로하는 모든 링크 setToken를 호출 할 수 있습니다. 대부분 코드를 재구성해야합니다. 당신이 좋아하는 것을 찾으려면 그걸로 어지럽히 야 할 것입니다. - route.cljs

(ns myapp.route 
    (:require [secretary.core :as secretary :include-macros true :refer [defroute]] 
      [myapp.views.welcome :as welcome] 
      [myapp.views.some :as some])) 

(defroute home "/" {} 
    (welcome/route)) 

(defroute some "/some" {} 
    (put! history-chan {:token "/some" 
         :view some/view})) 

-

(ns myapp.views.welcome 
    (:require [om.core :as om :include-macros true] 
      [sablono.core :as html :refer-macros [html]])) 

(declare view) 

(defn route [] 
    (put! history-chan {:token "/" 
         :view view})) 

(defn view [state owner] 
    (reify 
    om/IRender 
    (render [_] 
     (html [:div [:a {:href (route)}]])))) 

을 welcome.cljs 만 가능 하나

: 그냥 내 머리 위로 떨어져이 같은 일을 할 수 해결책.

+0

나쁘지 않아, 나쁘지 않아. 그러나 트릭은'defroute' 매크로에 있습니다. 'secretary'에서는 생성 된 명명 된 함수를 호출해야합니다.간단히'route '라고 부를 수는 없지만 토큰을주지 않을 것입니다. 단순히 위치가 바뀌면'secretary'가 부르는 것을 호출 할 것입니다. '놔! '. – skrat