【问题标题】:How to access user input from inside a module?如何从模块内部访问用户输入?
【发布时间】:2020-08-07 20:17:15
【问题描述】:

我正在尝试访问在模块中定义的一些用户输入。在下面的代码中,我有三个 pickerInput 选择,它们级联并依赖于前一个。最终的pickerInput (Level3) 将过滤mpg 数据集并将其显示在三个pickerInput 项下方。

我不确定如何访问 Level3 选择并在服务器的另一部分使用它,在本例中将其用作mpg 的过滤器。

下面是代码:

library(shiny)
library(tidyverse)
library(shinyWidgets)

multiFilterUI <- function(id){
    ns <- NS(id)
    
    tagList(
        fluidRow(
            column(3, uiOutput(ns("level1"))),
            column(3, uiOutput(ns("level2"))),
            column(3, uiOutput(ns("level3")))
        )
    )
}

multiFilterServer <- function(id, data, col1, col2, col3){
    moduleServer(
        id,
        function(input, output, session){
            output$level1 <- renderUI({
                ns <- session$ns
                cs <- unique(data[[col1]])
                
                pickerInput(ns("level1_select"), label = "Level1", choices = cs)
            })
            
            output$level2 <- renderUI({
                ns <- session$ns
                cs <- data %>% filter(!!sym(col1) %in% input$level1_select) %>%
                    distinct(!!sym(col2)) %>% 
                    pull(!!sym(col2))

                pickerInput(ns("level2_select"), label = "Level2", choices = cs)
            })
            
            output$level3 <- renderUI({
                ns <- session$ns
                cs <- data %>% filter(!!sym(col2) %in% input$level2_select) %>%
                    distinct(!!sym(col3)) %>% 
                    pull(!!sym(col3))
                
                pickerInput(ns("level3_select"), label = "Level3", choices = cs)
            })
        }
    )
}


ui <- fluidPage(
    multiFilterUI("test"),
    dataTableOutput("dt")
)

server <- function(input, output, session) {
    
    multiFilterServer("test", mpg, "manufacturer", "model", "trans")
    
    output$dt <- renderDataTable({
        mpg %>% filter(trans %in% input$level3_select)
    })
    
    
}

shinyApp(ui, server)

我的尝试只是访问level3_select,但它显然不起作用。

【问题讨论】:

    标签: r shiny shinymodules


    【解决方案1】:

    你需要return level3_select from the module as a reactive,你可以这样做:

    return(list(
            level3_select = reactive({input$level3_select})
            ))
    

    然后在 server 主函数中,您可以将模块的返回值存储在变量中。当您访问响应值时,您需要通过添加() 来评估它。

    library(shiny)
    library(tidyverse)
    library(shinyWidgets)
    
    multiFilterUI <- function(id){
      ns <- NS(id)
      
      tagList(
        fluidRow(
          column(3, uiOutput(ns("level1"))),
          column(3, uiOutput(ns("level2"))),
          column(3, uiOutput(ns("level3")))
        )
      )
    }
    
    multiFilterServer <- function(id, data, col1, col2, col3){
      moduleServer(
        id,
        function(input, output, session){
          output$level1 <- renderUI({
            ns <- session$ns
            cs <- unique(data[[col1]])
            
            pickerInput(ns("level1_select"), label = "Level1", choices = cs)
          })
          
          output$level2 <- renderUI({
            ns <- session$ns
            cs <- data %>% filter(!!sym(col1) %in% input$level1_select) %>%
              distinct(!!sym(col2)) %>% 
              pull(!!sym(col2))
            
            pickerInput(ns("level2_select"), label = "Level2", choices = cs)
          })
          
          output$level3 <- renderUI({
            ns <- session$ns
            cs <- data %>% filter(!!sym(col2) %in% input$level2_select) %>%
              distinct(!!sym(col3)) %>% 
              pull(!!sym(col3))
            
            pickerInput(ns("level3_select"), label = "Level3", choices = cs)
          })
          
          return(list(
            level3_select = reactive({input$level3_select})
            ))
        }
      )
    }
    
    
    ui <- fluidPage(
      multiFilterUI("test"),
      dataTableOutput("dt")
    )
    
    server <- function(input, output, session) {
      
      selection <- multiFilterServer("test", mpg, "manufacturer", "model", "trans")
      
      output$dt <- renderDataTable({
        mpg %>% filter(trans %in% selection$level3_select())
      })
      
      
    }
    
    shinyApp(ui, server)
    

    【讨论】:

    • 谢谢!你知道是否有任何其他方法可以解决这个问题,或者反应值是传递该输入的唯一方法吗?
    • 嗯,它必须是反应性的,这样闪亮的通知才会发生变化。我认为另一种选择是从模块中返回完整的input,然后你不需要用reactive({})包装它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多