What's the best way to use update* from outside a Shiny module without repeating the callModule() call or arguments?
Minimal example:
library(shiny)
numericInputModUI <- function (id) {
ns <- NS(id)
tagList(
numericInput(ns("val"), "Value", value = 0),
textOutput(ns("text"))
)
}
numericInputMod <- function (input, output, session,
updateVal = NA, displayText = "default text") {
output$text <- renderText(displayText)
if (!is.na(updateVal)) updateNumericInput(session, "val", value = updateVal)
}
ui = fluidPage(
numericInputModUI("module"),
actionButton("updateBad", label = "Bad Update"),
actionButton("updateBetter", label = "Better Update")
)
server = function(input, output, session) {
callModule(numericInputMod, "module", displayText = "original text")
observeEvent(
input$updateBad,
callModule(numericInputMod, "module", updateVal = 1)
)
observeEvent(
input$updateBetter,
callModule(numericInputMod, "module", updateVal = 2, displayText = "original text")
)
}
shinyApp(ui, server)
The Bad Update overrides the original text with the default. The Better Update avoids this by re-passing the original text but this isn't ideal because:
Ideally, one callModule() call would take care of specifying the module arguments and the update behaviour. I haven't found or thought up a way of doing this though.
You can do this with reactiveValues()
. You just need to make sure you allow for the reactive nature of the arguments you pass to the module:
library(shiny)
numericInputModUI <- function (id) {
ns <- NS(id)
tagList(
numericInput(ns("val"), "Value", value = 0),
textOutput(ns("text"))
)
}
numericInputMod <- function (input, output, session, updateVal = NA,
displayText = "default text", trig) {
output$text <- renderText(displayText())
observeEvent(trig(), ignoreInit = TRUE, {
updateNumericInput(session, "val", value = updateVal())
})
}
ui = fluidPage(
numericInputModUI("module"),
actionButton("updateBad", label = "Bad Update"),
actionButton("updateBetter", label = "Better Update")
)
server = function(input, output, session) {
vals <- reactiveValues(dText = "original text", uVal = NA, trig = 0)
observeEvent(input$updateBad, {
vals$dText <- "default text"
vals$uVal <- 1
vals$trig <- vals$trig + 1
})
observeEvent(input$updateBetter, {
vals$dText <- "original text"
vals$uVal <- 2
vals$trig <- vals$trig + 1
})
callModule(numericInputMod, "module",
displayText = reactive(vals$dText),
updateVal = reactive(vals$uVal),
trig = reactive(vals$trig))
}
shinyApp(ui, server)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.