2016-04-19 23 views
1

Ich habe Code, der das DOM aktualisiert. new-recipe! ruft eine API auf, um eine neue Rezepturkette zu erhalten. update-recipe-state next aktualisiert diesen Status auf dem Bildschirm. Schließlich haben wir einen Anruf an update-transition-buttons.Code nicht von Go-Block aufgerufen, aber es funktioniert von REPL

(defn- add-listener-to-recipe-button! [] 
    "Listens to go button, creates a new recipe and displays it" 
    (create-click-event-listener! (dommy/sel1 :#button-start) 
           #(go (new-recipe!) 
            (<! (timeout 2000)) 
            (update-recipe-state!) 
            (<! (timeout 2000)) 
            (update-transition-buttons! "onboarding")))) 

;; define your app data so that it doesn't get over-written on reload 
(defonce world 
    (add-listener-to-recipe-button!)) 

Die update-transition-buttons hat einige Verzögerungen zwischen den Schritten (mit dem Timeout-Code here) sieht wie folgt aus:

(defn- update-transition-buttons! [recipe-name] 
    "Updates the buttons with the transition names" 
    (go 
    ;; Split response in list of actions by splitting on the comma 
    (let [response (<! (http/get (get-recipe-transitions-url recipe-name))) 
      transition-names (clojure.string/split (:body response) ",")] 
     (go (update-buttons! transition-names) 
      (<! (timeout 2000)) 
      (js/console.log transition-names) 
      (set-button-event-handlers! transition-names))))) 

So teilt es die Antwort auf eine Zeichenfolge. updates-buttons ändert den Status auf der Seite durch Hinzufügen einiger Schaltflächen (dies ist sichtbar). Wieder gibt es eine Zeitüberschreitung, und dann möchte ich die Ereignishandler zu den Tasten hinzufügen. Hier läuft es schief.

Die Routine Ereignis-Listener wie folgt aussehen (die auch eine console.log enthalten) zu erstellen:

(defn- listen-to-transition-button! [name] 
    "Creates click event listener on button (button HTML ID should be name)" 
    (do (js/console.log (str "Listening to " name)) 
    (let [name-without-spaces (clojure.string/replace name " " "") 
      button (dommy/sel1 (keyword (str "#" name-without-spaces))) 
      action #(do (perform-action! name) 
         (update-recipe-state!))] 
     (create-click-event-listener! button action)))) 

(defn- set-button-event-handlers! [names] 
    "Creates click event listeners on the buttons (button ID should be name)" 
    (map listen-to-transition-button! names)) 

Wieder sehen Sie eine console.log Nachricht, die für die einzelnen Elemente geschehen soll, die übergeben wird. Der Ausgang I in der Firefox-Konsole erhalten ist:

[FIRST SERVICE GENANNT]
[NEXT SERVICE GENANNT]
[DISPLAY Liste der Schritte]: [ "Schritt 1", "Schritt 2", "Schritt 3"]

Was ich erwarte, ist:

[FIRST SERVICE GENANNT]
[NEXT SERVICE GENANNT]
[DISPLAY LI ST VON STEPS]: [ "Schritt 1", "Schritt 2", "Schritt 3"]
Anhören von Schritt 1
Hören Schritt 2
Hören Schritt 3

So ist die Event-Handler (die auf der abhängig HTML, das im vorherigen Schritt generiert wurde, wird aus irgendeinem Grund nicht hinzugefügt und die Nachricht console.log wird nicht angezeigt.

Wenn ich rufe die gleichen Code aus dem REPL ich die Ausgabe sehen Sie, d.h .:

repl => (Set-Taste-Ereignis-Handler![ "Schritt 1", "Schritt 2", "Schritt 3"])
(#object [Object [object Object]] #object [Object [object Object]] #object [Object [object Object]])

Und die Konsolenausgabe ist:

Anhören von Schritt 1
Hören Schritt 2
Hören Schritt 3

Warum kann set-button-event-handlers! aus dem REPL genannt werden, aber nicht i n die update-transition-buttons Methode nach update-buttons?

Antwort

6

sieht aus wie das Problem hier ist:

(map listen-to-transition-button! names) 

in set-button-event-handlers!

es schafft einen faulen seq, und Elemente, bis ihre Verwendung irgendwo im Code wird nicht realisiert (was nie passiert), aber Wenn Sie es in repl aufrufen, wird es vollständig realisiert, um alle Elemente in der Ausgabe zu zeigen. Versuchen Sie, diese Zeile zu ändern:

(doall (map listen-to-transition-button! names)) 
+0

Ja, das ist es. Vielen Dank!!! –