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

Shinylive部署R Shiny应用时出现TypeError: $table.DataTable不是函数

解决Shinylive部署DT表格渲染失败的问题

问题诊断

你遇到的TypeError: $table.DataTable is not a function错误,本质是Shinylive静态环境下DT组件的JavaScript依赖加载顺序或参数兼容性问题。本地运行正常是因为R Shiny的动态环境会自动处理依赖加载,但静态导出后,某些DT的配置参数会干扰JS库的初始化。

修复方案

针对你的代码,需要调整以下几点:

1. 避免在datatable初始化时引用未就绪的reactive值

原代码中selection = list(..., selected = selected_cells()),selected_cells()初始为NULL,在Shinylive静态加载时会导致DT初始化逻辑异常。改为在renderDT内部判断,仅当selected_cells()有值时才传入该参数。

2. 简化selectable参数的写法

原代码中selectable = -as.matrix(expand.grid(...))的写法在Shinylive中可能触发JS初始化错误,换成更简洁的索引排除方式。

3. 确保DT包版本兼容

更新DT到最新版本(>=0.30),Shinylive对新版DT的支持更完善:

install.packages("DT")

修改后的完整代码

library(shiny)
library(DT)
library(dplyr)
library(stringr)
library(tibble)

linebreaks <- function(n){HTML(strrep(br(), n))}
linebreaks_descriptors <- function(desc){HTML}

css <- "
#plTable table.dataTable tr.selected td, table.dataTable td.selected {
  box-shadow: inset 0 0 0 9999px #a8ddb5 !important;
}
"

shinyApp(
  ui = fluidPage(
    tags$style(HTML(css)),
    
    DTOutput("plTable"),
    
    fluidRow(p(linebreaks(1))),

    DTOutput("profileFilteredTable")
  ),
  server = function(input, output, session) {
    
    selected_cells <- reactiveVal(NULL)
    
    output$plTable <- renderDT({
      # 构建selection配置,仅当selected_cells有值时传入selected参数
      selection_config <- list(
        target = 'cell',
        selectable = -cbind(seq_len(nrow(mtcars)), 0)  # 简化索引排除写法
      )
      if(!is.null(selected_cells())){
        selection_config$selected <- selected_cells()
      }
      
      datatable(
        mtcars |> 
          select("cyl"),
        rownames = rownames(mtcars),
        options = list(searching = FALSE, lengthChange = FALSE,
                       scrollY = "200px",
                       paging = FALSE),
        selection = selection_config
      )
    })

    output$profileFilteredTable <- renderDT({
      if (is.null(input$plTable_cells_selected) ||
          nrow(input$plTable_cells_selected) == 0) {
        cyl_selected <- tibble()
      } else {
        cyl_selected <- input$plTable_cells_selected %>%
          as.data.frame() %>%
          as_tibble() %>%
          rename(car = V1, cyl = V2) %>%
          select("car")
          
        selected_cars <- mtcars |> 
          rowid_to_column("car_id") |> 
          semi_join(cyl_selected, by = c("car_id" = "car")) |>
          select("cyl") |> 
          distinct(cyl)
        
        cyl_selected <- selected_cars
      }

      if (nrow(cyl_selected) > 0) {
        filtered_prob_table <- mtcars |>
          semi_join(cyl_selected, by = "cyl") |>
          slice_sample(n = 1, by = "cyl")
      } else {
        filtered_prob_table <- mtcars |>
          slice_sample(n = 1, by = "cyl")
      }

      datatable(
        filtered_prob_table,
        rownames = rownames(filtered_prob_table),
        options = list(searching = FALSE, lengthChange = FALSE,
                       paging = FALSE, scrollY = "150px", scrollX = "900px"))
    })
  }
)

验证步骤

  1. 运行修改后的代码,确保本地正常工作。
  2. 重新执行导出命令:
shinylive::export(here("cars-reprex"), "site")
httpuv::runStaticServer("site")
  1. 打开浏览器访问静态服务,检查上方表格是否正常渲染,单元格选择功能是否可用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 01:20:08