查询->ast (om.next/query->ast '(:foo {:bar 1})) 给定查询表达式,返回AST。 ast->查询 (om.next/ast->query ) 给定查询表达式AST,将其解析为查询表达式。
问题:为什么需要这些功能?也就是说,为什么需要直接操作om中的查询抽象语法树(我假设它是表示查询树的clojure映射以及一些元数据)?
发布于 2016-02-28 09:26:45
在某些情况下,需要直接操作查询广播。在远程解析模式下,解析器希望您的读取函数返回{: remote -name true }或(可能修改的) {:remote-name AST-node} (在env中以:ast的形式出现)。通常,您必须修改AST以重新构造它或添加一些数据。
示例1:您有一个查询:[{:widget {:list [:name :created]}}] :widget部件是纯UI相关的,您的服务器不需要知道它的存在,它只关心/知道:list。基本上,您必须修改解析器中的AST:
(defmethod read :list
[{:keys [ast query state]} key _ ]
(let [st @state]
{:value (om/db->tree query (get st key) st)
:remote (assoc ast :query-root true)}))如果在发送函数中使用om/process-roots,它将从ast中提取:query-root并将查询从[{:widget {:list [:name :created]}}]重写为[{:list [:name :created]}]。
示例2:另一个示例是当您想在远程上更改某些内容时:
(defmethod mutate 'item/update
[{:keys [state ast]} key {:keys [id title]}]
{:remote (assoc ast :params {:data {:id id :title title })})在这里,您需要显式地告诉Om将您想要发送到AST中的数据包括进来。在您的遥控器上,您可以将:data拆分为更新给定id下的标题。
大多数情况下,您不会直接使用您在问题中描述的函数。解析器的每个方法中可用的env中都有ast。
发布于 2016-10-22 00:21:10
当我试图使用Compassus的时候,我偶然发现了一些东西:
假设您有一个复杂的联合/连接查询,其中包含参数子查询。就像这样:
`[({:foo/info
{:foo/header [:foo-id :name]
:foo/details [:id :description :title]}} {:foo-id ~'?foo-id
:foo-desc ~'?foo-desc})]现在,假设您希望设置参数,以便在服务器上使用om/解析器解析它,并将这些参数视为read分派的第三个参数。当然,可以编写一个函数,该函数将在查询中找到所有必要的参数并设置值。但这并不容易,就像我说的--想象一下您的查询可能相当复杂。
所以,您可以做的是修改ast,ast包括:children :params键。因此,假设:foo-id和:foo-desc的实际值处于:route-params键下的状态原子中:
(defn set-ast-params [children params]
"traverses given vector of `children' in an AST and sets `params`"
(mapv
(fn [c]
(let [ks (clojure.set/intersection (-> params keys set)
(-> c :params keys set))]
(update-in c [:params] #(merge % (select-keys params (vec ks))))))
children))
(defmethod readf :foo/info
[{:keys [state query ast] :as env} k params]
(let [{:keys [route-params] :as st} @state
ast' (-> ast
(update :children #(set-ast-params % route-params))
om/ast->query
om.next.impl.parser/expr->ast)]
{:value (get st k)
:remote ast'}))所以基本上你是:-抓取,用你想的实际值修改它,也许你可以马上把它发送到服务器。唉,不!还没。问题是,当您执行{:remote ast}时,Om将:query部分提取出来,并将其组成,然后将其发送到服务器。因此,您实际上需要:将修改后的ast转换为query,然后再将其转换回ast。
备注:
set-ast-params函数只适用于第一级(如果您有嵌套的参数化查询--它不能工作),使它是递归的--这并不困难:params的参数;;它修改查询,;;如果您有一个联接查询,它只需要其中的第一项。例如:[({:foo/foo :id :bar/bar :id} {:id ~'?id})] ;;将丢失其:bar部件(om.next.Im.parer/ ast ->expr);从ast检索查询;但不根据ast的:params键设置查询解析。;;还有(om/query->ast) ;;和(om.next.Im.解析器/expr>ast)https://stackoverflow.com/questions/35675766
复制相似问题