枚举命名空间并在 ClojureScript 中动态加载它们
Enumerate namespaces and dynamically load them in ClojureScript
这实际上可能有点 XY-problem,所以我会先解释一下目标是什么。
我正在构建一个由一组 Reagent components. It provides a user interface where you can dynamically add or remove UI elements. These UI elements (components) have a certain type. For example a Markdown component is-a
Text component. Whenever the user is presented with the option to add Text we list all the components that match the type+descendants 组成的 ClojureScript 应用程序(在本例中为 Markdown,可能还有其他)。
我的编码方式如下。
每个组件都在自己的命名空间中,这个命名空间包含一个构建器函数,returns 新组件。在命名空间的根部,它还调用 (derive ::type ::parent)
现在在一些不同的命名空间中,我们需要并在映射中枚举所有这些组件,例如:
(ns app.components
(:require
[app.gui.markdown :as markdown]
[app.gui.study-list :as study-list]))
(def all
{markdown/t markdown/builder
study-list/t study-list/builder})
其中 /t
指的是用于定义层次结构的命名空间限定关键字。我们使用 all
地图为面向用户的菜单提供数据(可以添加哪些组件,按类型过滤)。
现在,如您所想,这并不漂亮。因为它现在必须手动维护层次结构中所有类型的(可能)长列表。
我会做类似 (def all (components-of (descendants ::root)))
的事情,但我不确定如何解决这个问题,因为我认为这需要按名称查找变量(ClojureScript 不支持)。
所以我的问题是:如何在 ClojureScript 中(动态地)维护命名空间映射或列表 + 变量?
您不能动态地执行此操作,但据我所知,您的问题没有太大必要。 ClojureScript 宏可以反映回编译器——您可以轻松地使用 cljs.analyzer.api
命名空间来确定您需要哪些变量(通过 var 元数据或其他)并自动发出您想要的运行时信息映射。这实际上与 cljs.test/run-tests
的工作方式非常相似。它使用编译器过滤掉所有命名空间中附加了 :test
元数据的所有变量,并生成代码来测试每个变量。值得详细检查 cljs.test
以了解如何做到这一点。
这实际上可能有点 XY-problem,所以我会先解释一下目标是什么。
我正在构建一个由一组 Reagent components. It provides a user interface where you can dynamically add or remove UI elements. These UI elements (components) have a certain type. For example a Markdown component is-a
Text component. Whenever the user is presented with the option to add Text we list all the components that match the type+descendants 组成的 ClojureScript 应用程序(在本例中为 Markdown,可能还有其他)。
我的编码方式如下。 每个组件都在自己的命名空间中,这个命名空间包含一个构建器函数,returns 新组件。在命名空间的根部,它还调用 (derive ::type ::parent)
现在在一些不同的命名空间中,我们需要并在映射中枚举所有这些组件,例如:
(ns app.components
(:require
[app.gui.markdown :as markdown]
[app.gui.study-list :as study-list]))
(def all
{markdown/t markdown/builder
study-list/t study-list/builder})
其中 /t
指的是用于定义层次结构的命名空间限定关键字。我们使用 all
地图为面向用户的菜单提供数据(可以添加哪些组件,按类型过滤)。
现在,如您所想,这并不漂亮。因为它现在必须手动维护层次结构中所有类型的(可能)长列表。
我会做类似 (def all (components-of (descendants ::root)))
的事情,但我不确定如何解决这个问题,因为我认为这需要按名称查找变量(ClojureScript 不支持)。
所以我的问题是:如何在 ClojureScript 中(动态地)维护命名空间映射或列表 + 变量?
您不能动态地执行此操作,但据我所知,您的问题没有太大必要。 ClojureScript 宏可以反映回编译器——您可以轻松地使用 cljs.analyzer.api
命名空间来确定您需要哪些变量(通过 var 元数据或其他)并自动发出您想要的运行时信息映射。这实际上与 cljs.test/run-tests
的工作方式非常相似。它使用编译器过滤掉所有命名空间中附加了 :test
元数据的所有变量,并生成代码来测试每个变量。值得详细检查 cljs.test
以了解如何做到这一点。