3
(defn editing-mode? []
  "a hardcoded (for the moment) value, will look up in db later"
  false)

(def UP 38) ;; goog.events.KeyCodes.UP
(def DOWN 40) ;; goog.events.KeyCodes.DOWN
(def LEFT 37) ;; goog.events.KeyCodes.LEFT
(def RIGHT 39) ;; goog.events.KeyCodes.RIGHT
(def W 87) ;; goog.events.KeyCodes.W
(def S 83) ;; goog.events.KeyCodes.S
(def A 65) ;; goog.events.KeyCodes.A
(def D 68) ;; goog.events.KeyCodes.D
(def E 69) ;; goog.events.KeyCodes.E
(def ESC 27) ;; goog.events.KeyCodes.ESC

(defn delta [e]
  ;; e is a google closure Event
  (js/console.log (.-keyCode e))
  (js/console.log (editing-mode?))
  (match [(editing-mode?) (.-keyCode e)]
   [false 38] [:slide :up]
   [false 40] [:slide :down]
   [false 37] [:slide :left]
   [false 39] [:slide :right]
   [false 87] [:slide :up]
   [false 83] [:slide :down]
   [false 65] [:slide :left]
   [false 68] [:slide :right]
   [false 69] [:start-editing]
   [true 27]  [:done-editing]
   :else nil))

上面的代码有效。但是,如果我尝试不那么罗嗦,直接使用 goog 键码,就像这样

(match [(editing-mode?) (.-keyCode e)]
  [false goog.events.KeyCodes.UP] [:slide :up]
  [false goog.events.keyCodes.DOWN] [:slide :down]
  ...

我收到以下 cljsbuild 错误:

...
Caused by: clojure.lang.ExceptionInfo: Invalid local name: goog.events.KeyCodes.UP ...
...

好的,所以我不能使用goog.events.KeyCodes.*它们自己,但也许我可以使用def对它们的引用?所以我尝试

(match [(editing-mode?) (.-keyCode e)]
   [false UP] [:slide :up]
   [false DOWN] [:slide :down]
   ...

这确实可以编译,但现在匹配不起作用。每个关键事件都匹配[false UP]match 子句(core.match 总是发出[:slide :up])。

无论如何,第一个代码示例确实有效。但是为什么我不能在我的 core.match 匹配器中使用goog.events.KeyCodes.*或引用?goog.events.KeyCodes.*有什么我想念的吗?

4

3 回答 3

1

其中一个关键部分core.match是符号将绑定到值而不是匹配。即UP 查找并在匹配中使用的当前值;相反,符号在匹配时UP会绑定到该值。(.-keyCode e)false

不幸的是,据我所知,您对此无能为力core.match。它非常依赖于文字值。但是,由于您的模式相当简单,您可以使用(conp = ...).

于 2014-07-27T09:02:53.843 回答
1

您只能匹配本地绑定

      (= (let [x 2
               y 2]
           (match [x]
             [0] :a0
             [1] :a1
             [y] :a2
             :else :a3))
        :a2))

因此,您可以通过首先将键码绑定到局部变量来实现结果(let [...])

于 2015-04-26T13:50:48.957 回答
1

我喜欢通过简单地反转 KeyCodes 对象来构建“keyname”到“keycode”的映射:

(ns awesome.sauce
  (:require [clojure.set :as set])
  (:import [goog.events KeyCodes]))

(def codename
  (set/map-invert (js->clj KeyCodes)))

然后我可以用字符串而不是笨拙的互操作来识别键(字符串是值,所以可以很好地匹配):

(match [(editing-mode?) (codename (.-keyCode e))]
   [false "UP"] [:slide :up]
   [false "DOWN"] [:slide :down])
于 2015-06-18T06:42:39.623 回答