簡體   English   中英

R Shiny:從模塊外部使用更新*

[英]R Shiny: Use update* From Outside a Module

在不重復 callModule() 調用或參數的情況下,從 Shiny 模塊外部使用 update* 的最佳方法是什么?

最小的例子:

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)

Bad Update 使用默認值覆蓋原始文本。 Better Update 通過重新傳遞原始文本避免了這種情況,但這並不理想,因為:

  1. 它至少需要兩次 callModule() 調用。
  2. 您必須重復 callModule() 參數。

理想情況下,一個 callModule() 調用將負責指定模塊參數和更新行為。 我還沒有找到或想出一種方法來做到這一點。

您可以使用reactiveValues()做到這一點。 您只需要確保允許傳遞給模塊的參數具有反應性:

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM