这实际上可能是一个XY 问题,所以我将尝试首先解释目标是什么。
我正在构建一个由一组Reagent组件组成的 ClojureScript 应用程序。它提供了一个用户界面,您可以在其中动态添加或删除 UI 元素。这些 UI 元素(组件)具有一定的类型。例如 Markdown 组件is-a
Text 组件。每当用户看到添加 Text 的选项时,我们都会列出与 type+后代匹配的所有组件(在本例中为 Markdown,可能还有其他组件)。
我编码的方式如下。每个组件都在自己的命名空间中,这个命名空间包含一个返回新组件的构建器函数。在命名空间的根,它还调用(派生::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 中(动态地)维护名称空间 + 变量的映射或列表?