繁体   English   中英

如何观察和跟踪来自闪亮的两个 renderUI 元素的单个值

[英]How to observe and track a single value from two renderUI elements in shiny

这是一个简单的应用程序,用户可以在其中键入 (numericInput, bpm_numeric) 或滑动 (sliderInput, bpm_slider) 输入值。 这两个 UI 元素都应与任一选择保持同步。 但是,输出只需要跟踪一次。 下面我跟踪它两次,但我只需要用户的一份“选择/输入”副本。 我想我需要使用reactiveValues ,但我不确定该方法。

library(shiny)

ui <- fluidPage(

    titlePanel("Reverb & Delay Calculator"),

    sidebarLayout(
        sidebarPanel(
            uiOutput("bpm_numeric"),
            uiOutput("bpm_slider")
        ),
        mainPanel(
            p("Numeric value is:"),
            verbatimTextOutput("numeric_val"),
            p("Slider value is:"),
            verbatimTextOutput("slider_val")
        )
    )
)

server <- function(input, output, session) {

    output$bpm_numeric = renderUI({
        numericInput(
            "bpm_numeric",
            "BPM Numeric",
            value = 60, min = 40, max = 300
        )
    })

    output$bpm_slider = renderUI({
        sliderInput(
            "bpm_slider",
            "BPM Slider",
            value = 60, min = 40, max = 300
        )
    })

    # See how I can track "both", but really I only need to track "one" since
    # they should stay in-sync with one another. Maybe reactiveValues???
    output$numeric_val <- renderText({ input$bpm_numeric })
    output$slider_val <- renderText({ input$bpm_slider })

    observeEvent(input$bpm_numeric, {
        val = input$bpm_numeric
        updateSliderInput(session, "bpm_slider", value = val)
    })

    observeEvent(input$bpm_slider, {
        val = input$bpm_slider
        updateNumericInput(session, "bpm_numeric", value = val)
    })

}

shinyApp(ui = ui, server = server)

闪亮应用

注意:虽然我目前正在使用uiOuput() + renderUI() + update___Input() ,但这不一定是必需的。 如果输入 UI 保持同步,我对其他方法持开放态度,我有一份同步输出的副本。

这是一个想法。 它能够概括了一点,但它仍然依赖于你明知要以这种方式结合起来哪个ID。

对您当前示例的修改:

  1. 定义一个全局defbmp <- 60 ,有助于确保所有元素都从同一个位置开始。
  2. 在新的useval反应之外,将所有input$bpm_numeric_slider引用替换为useval()
  3. 用于状态跟踪,添加lastval反应值。
  4. 最后, useval <- eventReactive({},{})块,取决于每个要同步的元素。

最终产品(不包括ui组件,那里没有变化):

defbpm <- 60                                       # new

server <- function(input, output, session) {

    output$bpm_numeric = renderUI({
        numericInput(
            "bpm_numeric",
            "BPM Numeric",
            value = defbpm, min = 40, max = 300    # update
        )
    })

    output$bpm_slider = renderUI({
        sliderInput(
            "bpm_slider",
            "BPM Slider",
            value = defbpm, min = 40, max = 300    # update
        )
    })

    output$numeric_val <- renderText({ useval() }) # update
    output$slider_val <- renderText({ useval() })  # update

    lastval <- shiny::reactiveVal(defbpm)          # new
    useval <- eventReactive({
      input$bpm_numeric
      input$bpm_slider
    }, {
      newval <- setdiff(c(input$bpm_numeric, input$bpm_slider), lastval())
      if (length(newval) > 0) {
        if (newval != input$bpm_numeric) updateNumericInput(session, "bpm_numeric", value = newval)
        if (newval != input$bpm_slider) updateSliderInput(session, "bpm_slider", value = newval)
        lastval(newval)
      }
      lastval()
    })                                             # new

}

改善这一点的方法(我目前不知道):

  1. 以编程方式定义要保持同步的元素,例如 id 的character向量;
  2. 更新eventReactive以通过编程方式生成条件表达式,我目前还不是一个足以做到这一点的大师;
  3. 在运行时确定给定的 id 是否代表numericInputsliderInput (或其他东西),以便更通用地调用update*函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM