基于NSE实现Shiny.tag文本指定器动态变更的技术求助
动态修改Shiny标签类型并保持shiny.tag输出的解决方案
看起来你想要通过非标准求值(NSE)动态切换不同的HTML标签类型,同时确保输出始终是shiny.tag类型对吧?咱们先分析下你之前代码的问题,再给出可行的解决办法。
为什么你的尝试会出错?
- 第一个版本的代码里,你把
c的值当成文本内容传给了tags$p,所以最终输出的是<p>标签包裹着"h2"和你的文本,而不是调用tags$h2生成目标标签。 - 第二个版本里,
tags$UQE(c)的写法是错误的——tags是一个存储标签函数的列表,不能用$结合NSE语法来动态获取元素,而且你也没正确从tags中取出对应的函数就尝试调用,自然会报"attempt to apply non-function"的错误。
正确的实现方式
我们的核心目标是动态获取tags列表中对应的标签函数,然后调用它生成shiny.tag对象。这里提供两种常见的实现方式:
方式1:使用非标准求值(传入标签符号,如h2而非"h2")
library(htmltools) library(rlang) textSorter <- function(tag = a, text) { # 捕获传入的标签符号 tag_sym <- enquo(tag) # 将符号转为字符串,从tags列表中获取对应的标签函数 tag_func <- tags[[as_name(tag_sym)]] # 调用标签函数并传入文本 tag_func(text) }
测试一下:
# 生成h2标签 result <- textSorter(tag = h2, text = "Success!") result #> <h2>Success!</h2> # 验证类型 class(result) #> [1] "shiny.tag" # 默认生成a标签 default_result <- textSorter(text = "Default link") default_result #> <a>Default link</a>
方式2:直接传入标签名字符串(更简单的动态调用)
如果你觉得NSE的写法没必要,直接传字符串参数会更直观:
library(htmltools) textSorter_str <- function(tag = "a", text) { # 直接通过字符串索引tags列表获取函数并调用 tags[[tag]](text) }
测试:
result_str <- textSorter_str(tag = "h2", text = "Success with string!") result_str #> <h2>Success with string!</h2> class(result_str) #> [1] "shiny.tag"
额外说明
如果你想用更纯粹的NSE表达式写法,也可以用rlang::call2构造调用表达式再求值:
library(htmltools) library(rlang) textSorter_nse <- function(tag = a, text) { tag_expr <- enquo(tag) # 构造`tags$tag(text)`的表达式 call_expr <- call2(tags[[as_name(tag_expr)]], text) eval_tidy(call_expr) }
这个版本和方式1的效果完全一致,只是写法更偏向表达式构造。
内容的提问来源于stack exchange,提问作者Amit Kohli
相关产品推荐
相关产品推荐

