【问题标题】:Return the values of a list of inputs from a module从模块返回输入列表的值
【发布时间】:2020-05-16 18:33:36
【问题描述】:

我有一个模块,我在其中创建基于反应值的输入列表:如果此值为 3,则创建 3 个textInputs,等等。直到现在,当我需要从一个模块,我在模块的server 部分的末尾列出了return() 中的所有输入/值(有关更多详细信息,请参阅this article)。

但在这种情况下,由于输入的数量不是恒定的,我无法列出return() 中的所有输入。因此,我想创建一个可以返回的反应式列表。

考虑下面的例子:

library(shiny)

some_things <- c("drat", "mpg", "cyl")
numtextinputs <- length(some_things)

some_UI <- function(id) {
  ns <- NS(id)
  tagList(
    fluidRow(
      column(
        12,
        lapply(1:numtextinputs, function(x) {
          textInput(ns(some_things[x]),
                    label = some_things[x],
                    value = some_things[x])
        }),
        actionButton(ns("change"), "change inputs")
      )
    )
  )
}

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

  observeEvent(input$change, {

    test <- list()
    char_numtextinputs <- as.character(numtextinputs)

    for (x in char_numtextinputs) {
      local({
        test[[x]] <- input[[some_things[x]]]
      })
    }

    return(reactive({ test }) )
  })

}

ui <- fluidPage(
  actionButton("create_ui", "create ui"),
  uiOutput("ui"),
  verbatimTextOutput("display_changes")
)

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

  observeEvent(input$create_ui, {
    output$ui <- renderUI({
      some_UI("1")
    })
    list_of_variables <- callModule(some_server, "1")
  })

  output$display_changes <- renderText({
    if (exists("list_of_variables")){
      list_of_variables$test()
    }
    else {
      "list_of_variables$test does not exist"
    }
  })

}

shinyApp(ui, server)

在这个例子中,点击“create ui”会生成一个textInputs 列表。请注意,这里创建的textInputs 的数量是恒定的(我想举个简单的例子,在要创建的输入数量中添加一些反应性并不是很有用)。

预期结果:在生成textInputs 列表后,用户可以修改其中的值,完成后点击“更改输入”。然后,模块应将textInputs 中的值作为向量返回。 verbatimTextOutput 只是在这里验证这些值是否被很好地返回。请注意,答案应该适用于任意数量的textInputs(这就是我尝试列表和循环的原因)。

还问on Rstudio Community

【问题讨论】:

    标签: r shiny shinymodules


    【解决方案1】:

    更新:此应用将在 UI 模块中创建 3 个 textInput,并返回使用服务器模块提取的 textInput 值的向量并显示在 UI 中。这个原始示例中的一些已被略微修改或删除,以突出显示从模块中创建的输入返回值向量的答案。

    library(shiny)
    library(tidyverse)
    
    some_things <- c("drat", "mpg", "cyl")
    numtextinputs <- length(some_things)
    
    
    some_UI <- function(id) {
      ns <- NS(id)
      tagList(
        fluidRow(
          column(
            12,
            map(some_things, ~textInput(ns(.x), label = .x, value = .x ))
          )
        )
      )
    }
    
    some_server <- function(input, output, session) {
      #extract values of all the text boxes without explicitly naming them
      #by using the ids we used to create the textInputs
      test <- reactive({
        map_chr(some_things, ~input[[.x]])
      })
    
      #return the vector of values from module *note no () are needed after test
      # i.e. return(test) NOT return(test())
      return(test)
    }
    
    ui <- fluidPage(
    
      some_UI("1"),
      verbatimTextOutput("display_changes")
    )
    
    server <- function(input, output, session) {
    
      list_of_variables <- callModule(some_server, "1")
    
    
      output$display_changes <- renderText({
    
        list_of_variables()
    
    
      })
    
    }
    
    shinyApp(ui, server)
    

    【讨论】:

    • 这不是我的问题。正如我在帖子中所说,我知道如何生成textInputs 的反应数,但我没有把它放在我的帖子中,因为它会毫无意义地增加复杂性。我的问题是:如何将textInputs(在模块中)的值作为向量返回?通常,我的示例的整体结构没有任何变化,但您可以修改模块的uiserver 部分。
    • 啊,明白了。我更新了答案以显示您刚刚描述的内容 - 从模块返回 textInputs 值的向量。我将示例简化为仅包含 textInput UI 和输出向量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 2019-05-11
    相关资源
    最近更新 更多