如何在Shiny模块中正确使用shinyjs的onclick与toggle功能?
Shiny模块中shinyjs切换功能失效的问题修复
核心错误分析
- moduleServer参数顺序错误:你错误地将
shinyjs::useShinyjs()放在moduleServer的第一个参数位置,moduleServer的正确参数顺序是模块ID在前,服务器逻辑函数在后。另外shinyjs::useShinyjs()只需要在全局UI中加载一次,模块内部无需重复调用。 - 未处理模块命名空间ID:在模块服务器中使用
shinyjs函数时,直接使用"toggle"和"inputs"无法匹配DOM中实际的命名空间ID(比如tab1_inputs-toggle),必须通过session$ns()对ID进行转换。 - 模块调用ID不匹配:UI端调用模块的ID是
tab1_inputs,但服务器端调用的ID是tab1_input,两者不一致导致模块无法正确关联。
修正后的完整代码
# LIBRARIES ---- library(tidyverse) library(shiny) library(shinyWidgets) library(shinydashboard) library(shinyjs) # MODULES ---- module_wellPanel_input_UI <- function(id) { ns <- NS(id) tagList( fluidRow( column( width = 10, offset = 1, wellPanel( fluidRow( div( actionButton(ns("toggle"), "Toggle Inputs", icon = icon("toggle-on")) ), br(), div( id = ns("inputs"), div( class = "row", div( div( class = "col-md-2", pickerInput( inputId = ns("customer_id"), label = "Customer ID", choices = NULL, multiple = TRUE, selected = NULL, options = list( `actions-box` = TRUE, `deselect-all-text` = "Deselect All", `select-all-text` = "Select All", `none-selected-text` = "Nothing Selected", `selected-text-format` = "count > 1" ) ) ) ) ) ) %>% shinyjs::hidden() ) ) ) ) ) } module_wellPanel_input_Server <- function(id) { moduleServer( id, # 正确的参数顺序:先模块ID function(input, output, session) { ns <- session$ns # 获取当前模块的命名空间函数 shinyjs::onclick(id = ns("toggle"), { shinyjs::toggle(id = ns("inputs"), anim = TRUE, animType = "slide") }) } ) } # APP UI ---- ui <- tagList( useShinydashboard(), shinyjs::useShinyjs(), # 全局加载一次即可 navbarPage( title = "My Shiny App", tabPanel( title = "Home", icon = icon("home", lib = "font-awesome") ), tabPanel( title = "Panel 1", module_wellPanel_input_UI(id = "tab1_inputs") ) ) ) # APP SERVER ---- server <- function(input, output) { # 模块调用ID与UI端保持一致 module_wellPanel_input_Server(id = "tab1_inputs") } # RUN APP ---- shinyApp(ui, server)
内容的提问来源于stack exchange,提问作者The Rookie
相关产品推荐
相关产品推荐

