我在访问 Shiny 模块中的输入时遇到问题,其中 UI 是使用 HTML 模板或手动创建的 HTML 标签/输入定义的。具体来说,在使用这些自定义方法时,我无法从模块的服务器端访问输入值。此问题会影响导航和输入处理。
下面是一个简单的可复制的 Shiny 应用程序,演示了该问题:
在此示例中,我的 Shiny 应用程序中有两个按钮:一个是使用 actionButton() 创建的,另一个是使用 HTML 中的 Tags$button 手动创建的。两个按钮应该执行相同的操作,即导航到另一个模块 (mod2)。虽然闪亮按钮按预期工作,但自定义 HTML 按钮不会触发导航。
library(shiny)
# Module 1 UI
mod1_ui <- function(id) {
ns <- NS(id)
tagList(
h2("Module 1"),
actionButton(ns("button1"), "Shiny Button 1"),
tags$div(
tags$button(id = ns("button2"), "Custom HTML Button 2", class = "btn btn-primary")
)
)
}
# Module 1 Server
mod1_server <- function(id, change_page) {
moduleServer(id, function(input, output, session) {
observeEvent(input$button1, {
change_page("mod2")
})
observeEvent(input$button2, {
change_page("mod2")
})
})
}
# Module 2 UI
mod2_ui <- function(id) {
ns <- NS(id)
tagList(
h1("Module 2")
)
}
# Module 2 Server
mod2_server <- function(id) {
moduleServer(id, function(input, output, session) {
})
}
# Main UI
ui <- fluidPage(
uiOutput("dynamic_ui")
)
# Main Server
server <- function(input, output, session) {
current_page <- reactiveVal("mod1")
output$dynamic_ui <- renderUI({
if (current_page() == "mod1") {
mod1_ui("mod1_ui")
} else {
mod2_ui("mod2_ui")
}
})
mod1_server("mod1_ui", change_page = current_page)
mod2_server("mod2_ui")
}
shinyApp(ui = ui, server = server)
您需要分配 CSS 类
action-button
才能使其工作:
library(shiny)
# Module 1 UI
mod1_ui <- function(id) {
ns <- NS(id)
tagList(
h2("Module 1"),
actionButton(ns("button1"), "Shiny Button 1"),
tags$div(
tags$button(id = ns("button2"), type="button", "Custom HTML Button 2", class = "btn btn-primary action-button")
)
)
}
# Module 1 Server
mod1_server <- function(id, change_page) {
moduleServer(id, function(input, output, session) {
observeEvent(input$button1, {
change_page("mod2")
})
observeEvent(input$button2, {
change_page("mod2")
})
})
}
# Module 2 UI
mod2_ui <- function(id) {
ns <- NS(id)
tagList(
h1("Module 2")
)
}
# Module 2 Server
mod2_server <- function(id) {
moduleServer(id, function(input, output, session) {
})
}
# Main UI
ui <- fluidPage(
uiOutput("dynamic_ui")
)
# Main Server
server <- function(input, output, session) {
observe({
print(names(input))
})
current_page <- reactiveVal("mod1")
output$dynamic_ui <- renderUI({
if (current_page() == "mod1") {
mod1_ui("mod1_ui")
} else {
mod2_ui("mod2_ui")
}
})
mod1_server("mod1_ui", change_page = current_page)
mod2_server("mod2_ui")
}
shinyApp(ui = ui, server = server)
顺便说一句。你为什么不使用
actionButton()
并设置它的样式呢?