下面的代码示例生成简单的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”,则将不再观察到一个按钮。
当您再次调用某个模块时,似乎出了点问题,但是我不清楚具体原因。但是最有趣的问题是“ 如何使其工作?”
答案 0 :(得分:0)
那是因为您必须在绘制新表之前取消绑定。
您可以将无功导体传递到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)