admin管理员组

文章数量:1290935

Consider this example where if I dismiss the modal dialog, launch it again and then click the notification button, I get 2 notifications instead of 1. observeEvent has autoDestroy = TRUE then why does it not get destroyed when I dismiss the modal dialog? Is there a parameter in observeEvent that can fix this?

Reprex

library(shiny)
library(bslib)

# Module UI function
myModuleUI <- function(id) {
  # Empty UI
  tagList()
}

# Module server function
myModuleServer <- function(id) {
  moduleServer(id, function(input, output, session) {
    # Show modal when the module server is triggered
    showModal(modalDialog(
      title = "Modal from Module",
      actionButton(NS(id, "modalBtn"), "Click for notification"),
      footer = modalButton("Dismiss"),
      easyClose = TRUE
    ))
    
    # Observer for the modal button
    observeEvent(input$modalBtn, {
      showNotification("Hello from the module!", type = "message")
      removeModal()
    })
  })
}

# Main UI
ui <- page_fluid(
  card(
    card_header("Module Demo"),
    card_body(
      actionButton("triggerModule", "Show Modal")
    )
  ),
  myModuleUI("myModule")
)

# Main server
server <- function(input, output, session) {
  observeEvent(input$triggerModule, {
    myModuleServer("myModule")
  })
}

shinyApp(ui, server)

Consider this example where if I dismiss the modal dialog, launch it again and then click the notification button, I get 2 notifications instead of 1. observeEvent has autoDestroy = TRUE then why does it not get destroyed when I dismiss the modal dialog? Is there a parameter in observeEvent that can fix this?

Reprex

library(shiny)
library(bslib)

# Module UI function
myModuleUI <- function(id) {
  # Empty UI
  tagList()
}

# Module server function
myModuleServer <- function(id) {
  moduleServer(id, function(input, output, session) {
    # Show modal when the module server is triggered
    showModal(modalDialog(
      title = "Modal from Module",
      actionButton(NS(id, "modalBtn"), "Click for notification"),
      footer = modalButton("Dismiss"),
      easyClose = TRUE
    ))
    
    # Observer for the modal button
    observeEvent(input$modalBtn, {
      showNotification("Hello from the module!", type = "message")
      removeModal()
    })
  })
}

# Main UI
ui <- page_fluid(
  card(
    card_header("Module Demo"),
    card_body(
      actionButton("triggerModule", "Show Modal")
    )
  ),
  myModuleUI("myModule")
)

# Main server
server <- function(input, output, session) {
  observeEvent(input$triggerModule, {
    myModuleServer("myModule")
  })
}

shinyApp(ui, server)
Share Improve this question asked Feb 13 at 21:56 umair durraniumair durrani 6,1998 gold badges52 silver badges93 bronze badges 2
  • Consider setting arguments once = TRUE and ignoreInit = TRUE in observeEvent() – Ifeanyi Idiaye Commented Feb 13 at 22:38
  • @IfeanyiIdiaye, thanks for your comment. Using once = TRUE, ignoreInit = TRUE in observeEvent(input$modalBtn, {...}) has no effect, and using them in observeEvent(input$triggerModule, {...}) would launch the module with the first click only. Modal does not launch for subsequent clicks. – umair durrani Commented Feb 13 at 22:48
Add a comment  | 

1 Answer 1

Reset to default 2

The problem is that you are creating a new module server every time the trigger button is clicked. Instead of doing that, create it once and pass the input to the server.

library(shiny)
library(bslib)

# Module UI function
myModuleUI <- function(id) {
    # Empty UI
    tagList()
}

# Module server function
myModuleServer <- function(id, trigger) {
    moduleServer(id, function(input, output, session) {
        # Show modal when the module server is triggered
        observeEvent(trigger(),{
            showModal(modalDialog(
                title = "Modal from Module",
                actionButton(NS(id, "modalBtn"), "Click for notification"),
                footer = modalButton("Dismiss"),
                easyClose = TRUE
            ))
        })
        
        # Observer for the modal button
        observeEvent(input$modalBtn, {
            showNotification("Hello from the module!", type = "message")
            removeModal()
        })
    })
}

# Main UI
ui <- page_fluid(
    card(
        card_header("Module Demo"),
        card_body(
            actionButton("triggerModule", "Show Modal")
        )
    ),
    myModuleUI("myModule")
)

# Main server
server <- function(input, output, session) {
    myModuleServer("myModule", reactive(input$triggerModule))
}

shinyApp(ui, server)

It seems like when you pass inputs, you need to wrap them in a reactive() call.

本文标签: rWhy the observer does not get auto destroyed when created and used in a moduleStack Overflow