且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

闪亮-由动态生成的输入触发的观察()

更新时间:2023-10-24 16:05:04

我不是SHINY方面的专家,但似乎不可能用动态生成的输入触发一个观察者。我的解决方法基于以下答案:R shiny - last clicked button id

其思想是使用JavaScript函数跟踪所有动态生成的selectInput的上一次选择。该函数将使用上一次使用的selectedInput的ID更新闪亮的输入变量。

下面是您使用该解决方案修改的代码。请注意,因为我们需要区分动态生成的selectInput和其他selectInput,所以我用一个伪类将这些selectInput封装在一个div中。JavaScript函数将只对div中的那些对象做出反应。此外,这些函数将在JavaScript函数内生成一个随机数,以使观察者对同一selectInput中的更改做出反应。
library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(title = "Dynamic selectInput"),
  dashboardSidebar(
    sidebarMenu(
      menuItemOutput("menuitem")
    )
  ),
  dashboardBody(
    # keep track of the last selection on all selectInput created dynamically
    tags$script("$(document).on('change', '.dynamicSI select', function () {
                              Shiny.onInputChange('lastSelectId',this.id);
                              // to report changes on the same selectInput
                              Shiny.onInputChange('lastSelect', Math.random());
                             });"),            
    numericInput("graph_tytle_num","Number of Graph Title elements",value = 1,min = 1,max = 10),
    uiOutput("graph_title"),
    plotOutput("plot")
  )
)

server <- function(input, output, session) {
  output$menuitem <- renderMenu({
    menuItem("Menu item", icon = icon("calendar"))
  })

  #elements of graphic titles  
  output$graph_title <- renderUI({
    buttons <- as.list(1:input$graph_tytle_num)
    # use a div with class = "dynamicSI" to distinguish from other selectInput's
    div( class = "dynamicSI",
      lapply(buttons, function(i)
        column(3,
          selectInput(inputId = paste0("title_element",i),
                      label = paste("Title element",i),
                      choices = paste0(LETTERS[i],seq(1,i*2)),
                      selected = 1)
        )
      )
    )
  })

  # react to changes in dynamically generated selectInput's
  observe({
    input$lastSelect

    if (!is.null(input$lastSelectId)) {
      cat("lastSelectId:", input$lastSelectId, "
")
      cat("Selection:", input[[input$lastSelectId]], "

")
    }

    isolate({ #I dont want to have the numericInput input$graph_tytle_num to be a trigger
      #Create the graph title
      title <- c()
      for(i in 1:input[["graph_tytle_num"]]){
        title <- paste(title,input[[paste0("title_element",i)]])
      }

      output$plot <-renderPlot({hist(rnorm(100,4,1),
                                     breaks = 10,
                                     main = title)})
    })

  })  

}

shinyApp(ui, server)
最后,只需修改JavaScript函数上的选择器,就可以将此方法扩展到任何其他闪亮的小部件。例如,如果要使用actionButton,可以将eventselectorchangeselect更改为clickbutton