在Shiny模块中使用模态窗口

时间:2018-01-06 12:43:50

标签: r module shiny namespaces modal-dialog

我想在Shiny模块中使用模态窗口。用户与模态窗口交互,模块处理用户的输入。

在这个最小的例子中,模块应该在用户点击“关闭模态”按钮时删除模态:

library(shiny)

# Modal module UI
modalModuleUI <- function(id) {
  ns <- NS(id)
  actionButton(ns("openModalBtn"), "Open Modal")
}

# Modal module server
modalModule <- function(input, output, session) {

  myModal <- function() {
    modalDialog(
      actionButton("closeModalBtn", "Close Modal")
    )
  }
  # Show modal dialog on start up
  observeEvent(input$openModalBtn,
               ignoreNULL = FALSE,
               showModal(myModal())
               )

  # close modal on button click (not working)
  observeEvent(input$closeModalBtn, { 
    removeModal() 
  })
}

# Main app UI
ui <- fluidPage(modalModuleUI("foo"))

# Main app server
server <- function(input, output, session) {
  callModule(modalModule, "foo")
}

shinyApp(ui, server)

但是,单击“关闭模式”按钮不会触发模块服务器功能中的observeEvent()。我无法弄清楚如何访问(即观察)模块中模态窗口的内容。我想这是命名空间问题。

编辑:interactive example现在有效。请参阅下面的答案。

2 个答案:

答案 0 :(得分:7)

在仔细阅读this之后,我自己想通了。与renderUI一样,模态中的id元素需要包含在ns()中,以使它们在模块命名空间中可用。必须使用ns <- session$ns显式地在名称空间内加载名称空间,如下所示:

library(shiny)

# Modal module UI
modalModuleUI <- function(id) {
  ns <- NS(id)
  actionButton(ns("openModalBtn"), "Open Modal")
}

# Modal module server
modalModule <- function(input, output, session) {

  myModal <- function() {
    ns <- session$ns
    modalDialog(actionButton(ns("closeModalBtn"), "Close Modal"))
  }

  # open modal on button click
  observeEvent(input$openModalBtn,
               ignoreNULL = FALSE,   # Show modal on start up
               showModal(myModal())
  )

  # close modal on button click
  observeEvent(input$closeModalBtn, { 
    removeModal() 
  })
}

# Main app UI
ui <- fluidPage(modalModuleUI("foo"))

# Main app server
server <- function(input, output, session) {
  callModule(modalModule, "foo")
}

shinyApp(ui, server)

注意:如果myModal函数是在模块服务器函数之外定义的,则必须在调用时传递会话,即showModal(myModal(session))myModal <- function(session) {...}

我已更新example app以便它现在可以正常工作并添加了textInput。

答案 1 :(得分:0)

闪亮的modalButton()函数旨在实现这一目的。如果使用此名称,则无需担心任何名称空间问题。这是documentation。并且它在起作用。

library(shiny)

# Modal module UI
modalModuleUI <- function(id) {
  ns <- NS(id)
  actionButton(ns("openModalBtn"), "Open Modal")
}

# Modal module server
modalModule <- function(input, output, session) {

  myModal <- function() {
    modalDialog(
      footer = modalButton("Close Modal")
    )
  }
  # Show modal dialog on start up
  observeEvent(input$openModalBtn,
               ignoreNULL = TRUE,
               showModal(myModal())
  )
}

# Main app UI
ui <- fluidPage(modalModuleUI("foo"))

# Main app server
server <- function(input, output, session) {
  callModule(modalModule, "foo")
}

shinyApp(ui, server)