渲染函数的反应参数
Posted
技术标签:
【中文标题】渲染函数的反应参数【英文标题】:Reactive argument to render functions 【发布时间】:2018-06-15 10:51:34 【问题描述】:我在 flexdashboard 中有一个表格,其列数可以更改。我可以即时计算列的对齐方式(默认对齐方式将$23.45
视为字符向量,因此尽管它是一个数字并且应该右对齐但左对齐值)。问题是我不能将此对齐方式传递回renderTable
作为align
的值,因为它是一个反应值。
如何将反应对齐传递回renderTable
函数的align
参数? (或者让我用反应对齐方式渲染表格的替代方法)
MWE
---
title: "test"
output: flexdashboard::flex_dashboard
runtime: shiny
---
```r
library(flexdashboard)
library(shiny)
```
Inputs .sidebar
-------------------------------------
```r
selectInput(
"ncols",
label = "How many columns?",
choices = 1:5,
selected = 5
)
```
Column
-------------------------------------
### Test
```r
nc <- reactive(input$ncols)
aln <- reactive(substring('lllrr', 1, nc()))
renderTable(
x <- CO2[1:5, seq_len(nc()), drop = FALSE]
x[, 1] <- as.character(x[, 1])
x[3, 1] <- '<b>Mc1</b>'
x
, align = aln(), sanitize.text.function = function(x) x)
```
结果:
Warning: Error in .getReactiveEnvironment()$currentContext: Operation not
allowed without an active reactive context. (You tried to do something
that can only be done from inside a reactive expression or observer.)
【问题讨论】:
【参考方案1】:尝试将aln()
包装在renderText(...)
中,即
renderTable(
x <- CO2[1:5, seq_len(nc()), drop = FALSE]
x[, 1] <- as.character(x[, 1])
x[3, 1] <- '<b>Mc1</b>'
x
, align = renderText(aln()),
sanitize.text.function = function(x) x)
【讨论】:
我喜欢这个解决方案,因为我知道我错误地使用了反应元素,但没有意识到我可以只使用renderText
。天才,可以推广到很多情况。
我只想添加 - 这仅适用于renderTable
accepts arguments that can be called as functions。它不能推广到其他渲染函数。这也意味着reactive
和renderText
都不是必需的,您可以传入aln <- function() substring('lllrr', 1, nc())
、renderTable(..., align = aln)
之类的函数【参考方案2】:
首先,发生的具体错误是非常正确的。函数renderTable
只能在其第一个参数renderTable( ... , ...)
中保存反应式表达式。所有其他事物都必须是普通对象。因此,将反应值 aln()
放在常规环境中确实是在放置 reactive
。或者,从reactive
本身的角度来看,它是在没有主动响应上下文的情况下评估的,就像它在错误消息中所说的那样。
使这些东西也具有反应性的解决方法是包装renderTable
,即renderUI
。在renderUI
中,我们可以反应性地塑造包括对齐在内的整个表格渲染。 (解决方案部分改编自here。)
以下是您必须将renderTable
替换为:
renderUI(
output$table <- renderTable(
x <- CO2[1:5, seq_len(isolate(nc())), drop = FALSE]
x[, 1] <- as.character(x[, 1])
x[3, 1] <- '<b>Mc1</b>'
x
, align = aln(), sanitize.text.function = function(x) x)
tableOutput("table")
)
快速解释: 使用output
变量就像您在常规闪亮环境中使用一样,如果不是在markdown 中。 renderUI
将呈现的内容是对 renderTable
的引用,我们每次都会从头开始重新创建。
注意:我在renderTable
中使用了isolate
。原因如下:renderTable
是被动的,如果nc()
发生变化,它会更新。但这可能发生在周围的renderUI
对更改做出反应之前。你看,在这个中间步骤中,renderTable
尝试绘制具有不同列数的data.frame
,但align
仍然是之前的那个。抛出错误,因为它们不匹配。隔离内部 nc()
会阻止内部 renderTable
更新。但这没关系,因为外部的 renderUI
无论如何都会在轮到更新时执行此操作。
【讨论】:
感谢您提供此解决方案。这是非常有用的。 +1以上是关于渲染函数的反应参数的主要内容,如果未能解决你的问题,请参考以下文章