渲染函数的反应参数

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。天才,可以推广到很多情况。 我只想添加 - 这仅适用于renderTableaccepts arguments that can be called as functions。它不能推广到其他渲染函数。这也意味着reactiverenderText 都不是必需的,您可以传入aln &lt;- 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

以上是关于渲染函数的反应参数的主要内容,如果未能解决你的问题,请参考以下文章

从异步函数渲染反应本机孩子

构造函数和渲染方法在反应组件中运行两次

渲染后调用的函数反应原生

反应路由器不渲染组件然后他有参数

是否可以在反应渲染函数中返回空?

你能解释一下这个反应原生代码(渲染方法中的奇怪箭头函数)吗?