如何从模块内部访问用户输入?

How to access user input from inside a module?

我正在尝试访问模块中定义的一些用户输入。在下面的代码中,我有三个 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,但显然行不通。

您需要 return level3_select from the module as a reactive,您可以使用:

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

然后在主server函数中,您可以将模块的return值存储在一个变量中。当您访问反应值时,您需要通过添加 ().

来评估它
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)