You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在手动拖动rhandsontable行后更新输出内容?

解决rhandsontable拖动行后仅首次触发更新的问题

问题核心在于两个关键点:

  1. Shiny输入值重复不触发更新:默认情况下,Shiny.setInputValue若传入的对象内容与上次一致,Shiny不会检测到变化,也就不会触发后续的observeEvent。
  2. 重复绑定钩子:每次渲染rhandsontable时,原代码都会重复添加afterRowMove钩子,可能导致逻辑冲突。

修改后的完整代码

library(tidyverse)
library(shiny)
library(rhandsontable)
library(htmlwidgets)

underlying_table_data <- data.frame("Names" = c("A", "B", "C"), "Value" = c(0,0,0))

jsCode <- c(
    "function(el, x) {",
    "  // 先移除已存在的钩子,避免重复绑定",
    "  Handsontable.hooks.remove('afterRowMove', this.rowMoveHook);",
    "  // 定义钩子函数并保存引用",
    "  this.rowMoveHook = function(movedRows, finalIndex, dropIndex, movePossible, orderChanged){",
    "    Shiny.setInputValue('newRow', {",
    "      movedRows: movedRows,",
    "      finalIndex: finalIndex,",
    "      dropIndex: dropIndex,",
    "      movePossible: movePossible,",
    "      orderChanged: orderChanged,",
    "      timestamp: Date.now() // 添加时间戳确保每次输入值唯一",
    "    });",
    "  };",
    "  Handsontable.hooks.add('afterRowMove', this.rowMoveHook);",
    "}"
)

ui <- fluidPage(
    rHandsontableOutput("table"), 
)

server <- function(input, output) {

    values <- reactiveValues(data = underlying_table_data)

    output$table <- renderRHandsontable({
        rhandsontable(values$data, manualRowMove = TRUE, readOnly = TRUE) %>%
            onRender(jsCode)
    })

    observeEvent(input$newRow, {
        # 仅当行顺序确实改变时执行更新
        if(!is.null(input$newRow$movedRows) && input$newRow$orderChanged){
            values$data[3, 'Value'] <- 1
        }
    }, ignoreInit = TRUE) # 忽略初始化时的触发
}

shinyApp(ui = ui, server = server)

关键修改说明

  • 添加时间戳:在JS的Shiny.setInputValue中加入timestamp: Date.now(),确保每次触发时传入的对象都有唯一值,强制Shiny检测到输入变化。
  • 钩子管理:先移除已存在的afterRowMove钩子再重新添加,避免重复绑定导致的多次触发或冲突。
  • 调整监听逻辑:监听整个input$newRow对象,并添加ignoreInit = TRUE避免初始化时误触发;同时通过orderChanged判断行顺序是否真的改变,减少不必要的更新。

内容的提问来源于stack exchange,提问作者anonanonan87

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 01:45:03