【问题标题】:Re-use reactive elements defined in modules重用模块中定义的反应元素
【发布时间】:2020-02-21 23:42:41
【问题描述】:

我正在制作一个应用程序,用户可以在其中创建任意数量的表格,并显示使用shinymeta 重新制作每个单独表格所需的代码。我可以为这些表中的每一个生成代码,但是当我想创建一个显示每个表的每个代码的完整模式时遇到了问题。

为了更清楚,这里有一个可重现的例子:

library(shiny)
library(dplyr)
library(shinymeta)

module_ui <- function(id){
  ns <- NS(id)

  tagList(
    fluidRow(
      actionButton(ns("show_table"), "Show table"),
      actionButton(ns("show_code"), "Show code"),
      tableOutput(ns("table"))
    )
  )
}

module_server <- function(input, output, session){
  data <- metaReactive2({
    req(input$show_table)

    isolate(metaExpr({
      mtcars 
    }))
  })

  data2 <- metaReactive({
    ..(data()) %>%
      select(mpg)
  })

  output$table <- renderTable({
    data2()
  })

  observeEvent(input$show_code, {
    showModal(modalDialog(
      renderPrint({
        expandChain(data(), data2())
      })
    ))
  })

  return(data())
}

ui <- fluidPage(
  actionButton("launch", "Launch"),
  actionButton("show_full_code", "Show the full code (at least 2 'launch' before)")
)

server <- function(input, output, session) {

  count <- reactiveValues(value = 0)

  observeEvent(input$launch, {
    count$value <- count$value + 1
    insertUI(selector = "#show_full_code",
             where = "afterEnd",
             ui = module_ui(paste0("x", count$value)))
    callModule(module_server, paste0("x", count$value))
  })

  #### "Merge" the single code modals in one big
  observeEvent(input$show_full_code, {
    showModal(modalDialog(
      renderPrint({
        expandChain(x1_data)
      })
    ))
  })

}

shinyApp(ui, server)

当您单击“启动”时,会生成两个按钮,您可以显示一个表格(“显示表格”)和重新制作该表格的代码(“显示代码”)。可以无限点击“Launch”,表格将命名为x1_datax2_data等。

但是,当我尝试生成合并每个单独代码的代码时(通过单击“显示完整代码”),找不到x1_data。使用x1_data() 也不起作用。我不喜欢在一篇文章中问两个问题,但我现在会这样做:

  • 如何访问在模块中创建的反应性元素?
  • 如何将每个单独的代码“合并”成一个大代码?

也在RStudio Community问过

编辑:在评论之后,我在示例中添加了第二个反应式表达式,因此我不能对它们都使用return

【问题讨论】:

  • 你可以拥有模块服务器功能return数据框对象:stackoverflow.com/questions/46596172/…
  • 在模块末尾添加 return(data()) 并不能解决问题,即使解决了,我也有几个反应式表达式,我无法全部返回(我编辑了帖子)
  • 您可以返回反应数据帧和反应向量的列表以及其他任何内容。我一直这样做是为了管理模块数据和用户输入。
  • 当我在模块部分的末尾添加return(list(data(), data2())) 时,仍然找不到x1_data(在expandChain 中)。您有工作示例要分享吗?

标签: r shiny


【解决方案1】:

好的,我想出了一个答案,让模块返回 expandChain() 结果,而不是尝试在服务器中再次呈现它们:

library(shiny)
library(dplyr)
library(shinymeta)

module_ui <- function(id){
  ns <- NS(id)

  tagList(
    fluidRow(
      actionButton(ns("show_table"), "Show table"),
      actionButton(ns("show_code"), "Show code"),
      tableOutput(ns("table"))
    )
  )
}

module_server <- function(input, output, session){
  data <- metaReactive2({
    req(input$show_table)

    isolate(metaExpr({
      mtcars 
    }))
  })

  data2 <- metaReactive({
    ..(data()) %>%
      select(mpg)
  })

  output$table <- renderTable({
    data2()
  })

  observeEvent(input$show_code, {

    showModal(modalDialog(
      renderPrint({
        expandChain(data(), data2())
      })
    ))


  })
  ########################################
  ### create list of reactive objects ####
  ########################################
  return(list(
    expandChain(data(), data2())
  )
  )

}

ui <- fluidPage(
  actionButton("launch", "Launch"),
  actionButton("show_full_code", "Show the full code (at least 2 'launch' before)")
)

server <- function(input, output, session) {

  count <- reactiveValues(value = 0)


  observeEvent(input$launch, {
    count$value <- count$value + 1
    insertUI(selector = "#show_full_code",
             where = "afterEnd",
             ui = module_ui(paste0("x", count$value)))
     callModule(module_server, paste0("x", count$value))


  })

  #### "Merge" the single code modals in one big list object
  my_data <- reactive({
    req(count$value)

    my_set <- 1:count$value

    ### lapply through the different name spaces so all are captured ###     
    final <- lapply(my_set, function(x){
      temp <- callModule(module_server, paste0("x", x))
      return(temp)
    })

    return(final)
  })


  #### "Merge" the single code modals in one big
  observeEvent(input$show_full_code, {
    showModal(modalDialog(
      renderPrint({

        temp <- sapply(unlist(my_data()), function(x){
          print(x)
        })

      })
    ))
  })

}

shinyApp(ui, server)

【讨论】:

  • 谢谢!有时我必须在“显示完整代码”按钮上单击两次,但这没什么大不了的。还有一件事,你知道如何去掉打印出来的代码中的[[1]][[2]]...吗?
  • 调整答案使用sapply打印输出
  • 完美,非常感谢(只是最后有点小问题,少了一个括号和一个括号)
  • 复制粘贴失败 - 现在应该没问题了。
猜你喜欢
  • 2021-11-18
  • 2018-03-17
  • 2019-12-13
  • 2015-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多