【问题标题】:Incorrect behavior of Observe on actionButton in DT::DTOutput in shiny module在闪亮模块中的 DT::DTOutput 中观察 actionButton 的行为不正确
【发布时间】:2019-01-08 02:04:21
【问题描述】:

下面的代码示例生成简单的 shinyApp,其中包含数字输入和数据表,其中包含行中的按钮。数据表中的行数与数字输入相同。此外,每个按钮都会被观察并在按下时生成警报。

library(shiny)
library(DT)
library(shinyjs)

exampleModuleUI <- function(id) {
    ns <- NS(id)

    DT::DTOutput(ns("table"))
}

exampleModule <- function(input, output, session, max.index) {
    ns <- session$ns

    output$table <- renderDataTable(
        data.frame(
            buttons = unlist(
                lapply(
                    1:max.index, 
                    function(index) {
                        as.character(
                            actionButton(
                                ns(as.character(index)), 
                                as.character(index)
                            )
                        )
                    }
                )
            )
        ),
        escape = FALSE, 
        style = 'bootstrap',
        extensions = 'FixedColumns',
        options = list(
            preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
            drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
        )
    )

    lapply(
        1:max.index, 
        function(index) {
            observeEvent(input[[as.character(index)]], {
                shinyjs::alert(as.character(index))
            })
        }
    )
}

ui <- fixedPage(
    useShinyjs(),
    numericInput(
        "count", 
        "Count of button in table",
        value = 3,
        min = 3, 
        max = 7, 
        step = 1
    ),
    exampleModuleUI("dt.table")
)

server <- function(input, output, session) {
    max.count <- reactive({
        input$count
    })

    observeEvent(
        max.count(), {
            callModule(exampleModule, "dt.table", max.count())
        }
    )
}

shinyApp(ui, server)

问题
如果在数字输入中首先输入例如“7”,然后输入“6”,然后再输入“7”,则不会再观察到任何按钮。 当您再次调用某个模块时,似乎出现了问题,但我不清楚具体原因。但最有趣的问题是“如何让它发挥作用?

【问题讨论】:

    标签: shiny dt shinyjs action-button


    【解决方案1】:

    那是因为你必须在绘制新表格之前解除绑定。

    您可以将反应导体传递给max.index,而不是多次调用该模块。

    我还添加了一个反应值,它收集已经存在的观察者,以便不多次定义它们。

    library(shiny)
    library(DT)
    library(shinyjs)
    
    exampleModuleUI <- function(id) {
      ns <- NS(id)
      DT::DTOutput(ns("table"))
    }
    
    exampleModule <- function(input, output, session, max.index) {
      ns <- session$ns
    
      output$table <- renderDataTable(
        data.frame(
          buttons = unlist(
            lapply(
              1:max.index(), 
              function(index) {
                as.character(
                  actionButton(
                    ns(as.character(index)), 
                    as.character(index)
                  )
                )
              }
            )
          )
        ),
        escape = FALSE, 
        style = 'bootstrap',
        extensions = 'FixedColumns',
        options = list(
          preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
          drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
        )
      )
    
      observers <- reactiveVal(NULL) # to store the existing observers
    
      observeEvent(max.index(), {
        runjs('Shiny.unbindAll($("#dt-table").find("table").DataTable().table().node());')
        lapply(
          setdiff(1:max.index(), observers()), 
          function(index) {
            observers(c(observers(),index)) # add index to the existing observers
            observeEvent(input[[as.character(index)]], {
              shinyjs::alert(as.character(index))
            }, ignoreInit = TRUE)
          }
        )
      })
    }
    
    ui <- fixedPage(
      useShinyjs(),
      numericInput(
        "count", 
        "Count of button in table",
        value = 3,
        min = 3, 
        max = 7, 
        step = 1
      ),
      exampleModuleUI("dt")
    )
    
    server <- function(input, output, session) {
    
      max.count <- reactive({
        input$count
      })
    
      callModule(exampleModule, "dt", max.count)
    
    }
    
    shinyApp(ui, server)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-30
      • 2020-01-18
      • 2020-05-28
      • 1970-01-01
      • 2023-03-25
      • 2019-10-25
      • 2019-03-12
      • 2018-03-16
      相关资源
      最近更新 更多