2016-05-13 12 views
5

इस रूप में Quick Start tutorial कहते हो रहा हो प्रतीत नहीं होता:जब राज्य परिवर्तन होता है तो ओम अगला घटक फिर से प्रस्तुत क्यों नहीं करता है?

ओम में अगला आवेदन राज्य परिवर्तन एक reconciler द्वारा प्रबंधित कर रहे हैं। reconciler नवीनता स्वीकार करता है, इसे एप्लिकेशन स्थिति में विलीन कर देता है, उनके घोषित प्रश्नों के आधार पर सभी प्रभावित घटकों को पाता है, और शेड्यूल पुनः शेड्यूल करता है।

जब मैं चयन बॉक्स बदलता हूं तो म्यूटेट फ़ंक्शन राज्य को अद्यतन करता है, लेकिन ऐप घटक का रेंडर फ़ंक्शन कभी निष्पादित नहीं होता है। मैं आरईपीएल में @ ऐप-स्टेट के साथ देख सकता हूं कि राज्य बदल गया है और मैं ऐप के रेंडर फ़ंक्शन में प्रिंस में कंसोल में आउटपुट कभी नहीं देखता हूं।

[1955.847s] [om.next] transacted '[(om-tutorial.core/switch-topic {:name "b"})], #uuid "c3ba6741-81ea-4cbb-8db1-e86eec26b540" 
"read :default" :topics 

अगर मैं (swap! app-state update-in [:current-topic] (fn [] "b")) साथ आरईपीएल से राज्य को अद्यतन फिर ऐप्स के प्रस्तुत करना फ़ंक्शन निष्पादित करता है: यह मैं कंसोल में सभी देखें है।

"read :default" :topics 
"read :default" :current-topic 
"App om-props " {:topics [{:name "a"} {:name "b"}], :current-topic "b"} 
"Topics om-props " {:topics [{:name "a"} {:name "b"}]} 

यहाँ पूर्ण कोड है::

(ns om-tutorial.core 
    (:require [goog.dom :as gdom] 
      [om.next :as om :refer-macros [defui]] 
      [om.dom :as dom])) 

(enable-console-print!) 

(def app-state (atom {:current-topic "a" :topics [{:name "a"} {:name "b"}]})) 

(defmulti read (fn [env key params] key)) 

(defmethod read :default 
    [{:keys [state] :as env} key params] 
    (prn "read :default" key) 
    (let [st @state] 
    (if-let [value (st key)] 
     {:value value} 
     {:value :not-found}))) 

(defmulti mutate om/dispatch) 

(defmethod mutate 'om-tutorial.core/switch-topic 
    [{:keys [state]} _ {:keys [name]}] 
    {:action 
    (fn [] 
    (swap! state update-in 
     [:current-topic] 
     #(identity name)))}) 

(defui Topics 
    static om/IQuery 
    (query [this] 
     [:topics]) 
    Object 
    (render [this] 
      (let [{:keys [topics] :as props} (om/props this)] 
      (prn "Topics om-props " props) 
      (apply dom/select #js {:id "topics" 
            :onChange 
            (fn [e] 
            (om/transact! this 
                `[(switch-topic ~{:name (.. e -target -value)})]))} 
        (map #(dom/option nil (:name %)) topics))))) 

(def topics-view (om/factory Topics)) 

(defui App 
    static om/IQuery 
    (query [this] 
     '[:topics :current-topic]) 
    Object 
    (render [this] 
      (let [{:keys [topics current-topic] :as om-props} (om/props this)] 
      (prn "App om-props " om-props) 
      (dom/div nil 
        (topics-view {:topics topics}) 
        (dom/h3 nil current-topic))))) 

(def reconciler 
    (om/reconciler 
    {:state app-state 
    :parser (om/parser {:read read :mutate mutate})})) 


(om/add-root! reconciler App (gdom/getElement "app")) 

यहाँ project.clj फ़ाइल है: यहाँ कंसोल आउटपुट है

(defproject om-tutorial "0.1.0-SNAPSHOT" 
    :description "My first Om program!" 
    :dependencies [[org.clojure/clojure "1.7.0"] 
       [org.clojure/clojurescript "1.7.170"] 
       [org.omcljs/om "1.0.0-alpha24"] 
       [figwheel-sidecar "0.5.0-SNAPSHOT" :scope "test"]]) 

उत्तर

1

मैं अपने आवेदन में एक ही मुद्दा था और एक वर्कअराउंड मिला (हालांकि यह सबसे अच्छा समाधान नहीं हो सकता है)। आप मूल घटक के ओम गुणों को पार कर अपने घटकों का निर्माण कर सकते हैं।

आपका ui अनुप्रयोग तो इस प्रकार दिखाई देगा सकता है:

(defui App 
    Object 
    (render [this] 
      (dom/div nil (topics-view (om/props this))))) 

IQuery निश्चित रूप से बेहतर उपाय है, लेकिन मैं अभी भी आप की तरह एक ही मुद्दा है। यह कामकाज अब मेरी परियोजनाओं में काम करता है और मैं निश्चित रूप से IQuery पर एक नज़र डालेगा।

संपादित

ट्यूटोरियल के बारे में बताते हैं Components, Identity and Normalization आप यूआई अद्यतन करने के लिए जब यह आवश्यक है क्या करना है। इसका परिणाम अधिक मूर्खतापूर्ण समाधान में होता है।

0

ओम अगला उनके लिए पढ़ने के कार्यों को अनावश्यक रूप से कॉल करने से बचने और बेकार पुन: प्रस्तुत करने से बचने के लिए प्रदर्शन कारणों से प्रश्नों पर पुन: पढ़ने के बारे में अनिच्छुक है।

(om/transact! this 
    `[(switch-topic ~{:name (.. e -target -value)}) 
    :current-topic]) 

संदर्भ:: https://github.com/omcljs/om/wiki/Documentation-(om.next)#transact

निर्दिष्ट करने के लिए है कि घटक है कि क्वेरी :current-topic चाहिए फिर से प्रस्तुत करना (और प्रासंगिक पढ़ने समारोह कहा जाता है), तो आप चलाना वेक्टर के अंत में इन कुंजियों प्रदान कर सकते हैं
संबंधित मुद्दे