我有一个闪亮的应用程序,它输出了一个带有可选行的数据表。当单击一行时,它会被捕获并保存到reactiveVals(slct
)。在我的完整应用程序中,检查被应用到选定的行,dataTableProxy
用于更新表中选定的行。最后,执行显示第二表格的功能。
不幸的是,当这个函数花费的时间超过两次单击之间的时间时,表就会陷入选择和取消选择最近单击的行的循环。
我认为这是因为更改没有及时注册,然后dataTableProxy循环,并迭代地应用这两个更改。
最小重复:
library(shiny)
library(DT)
library(dplyr)
ui <- function () {
fluidPage(
DTOutput("tbl"),
DTOutput("tbl2")
)
}
server <- function (input, output, session) {
# initialise objects
df = data.frame(a = 1:5)
slct <- reactiveVal(NULL)
# create DT and proxy
output$tbl <- renderDT(df)
proxy <- dataTableProxy("tbl")
# update proxy and selection reactive, when rows are selected
observe({
rows <- input$tbl_rows_selected
max_selected = 3
if (length(rows) > max_selected) {
# drop the second-last clicked row
rows <- rows[c(1:(max_selected - 1), length(rows))]
}
slct(rows)
DT::selectRows(proxy, rows)
})
# perform a slow function, then output the selected rows
output$tbl2 <- renderDT({
df_selected <- slow_function(df, slct)
datatable(df_selected)
})
}
slow_function <- function (df, slct) {
Sys.sleep(0.5)
slice(df, slct())
}
runApp(list(ui = ui, server = server))
字符串
我在以前的应用程序上也遇到过这个问题,因为我在网上找不到任何信息,我希望有人能帮忙!我能想到的解决方案是:
1.在进行任何处理时禁用所选内容或整个datatable
1.找到一种方法来识别循环是否正在发生并阻止它
1.一个实际的修复程序,以停止具有这种行为的datatable
但我想不出一个好方法来做这些事情。
如果它与任何解决方案相关,对于完整的应用程序,datatable还启用了RowReorder
扩展,带有JS回调,在Shiny模块中设置,并启用了server=T
。
1条答案
按热度按时间pod7payv1#
好吧,感谢@thothal的评论,我试着把
DT::selectRows
调用放在相关的if语句中(这本来不在我的问题中)。据我所知,这现在起作用了,因为当更新行的循环最终结束时,有一个结束情况,因为max_selected将下降到足够低,因此不会输入语句。
更新了
observe
的代码:字符串