添加formatStyle后Shiny应用全白无输出故障排查
从你的代码和描述来看,导致整个Shiny应用输出消失的原因大概率是前端JavaScript层面的静默错误(R控制台不会抛出这类错误,但会导致页面渲染崩溃),结合你的代码细节,主要有以下几个问题点:
1. Reactive对象调用缺失括号
你传入的count_platform是一个Shiny reactive对象(从count_platform()的调用可以看出),但在提取数据时却没有加括号:
data <- count_platform[,c('PLATFORM', 'Population')]
正确的写法应该是调用reactive对象获取数据:
data <- count_platform()[,c('PLATFORM', 'Population')]
如果不加括号,data会是reactive对象本身而非数据框,后续datatable和formatStyle处理时会在前端触发无法捕获的错误,导致整个页面输出失效。
2. 字符串大小写不匹配导致样式映射失败
你在定义my_colors时使用的是'No platform'(小写p),但前面注释里的背景色判断用的是'No Platform'(大写P),而实际数据中的PLATFORM值应该是'No Platform'(从unique(count_platform()$PLATFORM)的结果来看)。这种大小写不一致会让styleEqual无法正确匹配,导致样式渲染逻辑出错:
my_colors <- ifelse(my_vals == 'No platform', 'red', 'blue') # 这里的小写p是问题
修正为和实际数据一致的字符串:
my_colors <- ifelse(my_vals == 'No Platform', 'red', 'blue')
3. JS回调中Input ID未加引号
在拼接Shiny输入ID时,你没有给row_name添加引号,这会导致JS将其视为变量而非字符串ID:
paste0("table.on('click.dt', 'td', function() { var row_=table.cell(this).index().row; var col=table.cell(this).index().column; var rnd= Math.random(); var data = [row_, col, rnd]; Shiny.onInputChange(", row_name, ",data ); });")
正确的写法应该给row_name加上单引号,确保JS识别为字符串:
paste0("table.on('click.dt', 'td', function() { var row_=table.cell(this).index().row; var col=table.cell(this).index().column; var rnd= Math.random(); var data = [row_, col, rnd]; Shiny.onInputChange('", row_name, "', data); });")
修正后的完整代码
create_platform_table <- function(count_platform, row_name) { # 注意:这里定义的background变量未被使用,可以考虑移除或利用起来 background <- "value == 'No Platform' ? '#5EDD6B' : value != 'else' ? '#FFBF33' : ''" class(background) <- "JS_EVAL" my_vals <- as.character(unique(count_platform()$PLATFORM)) # 修正大小写匹配问题 my_colors <- ifelse(my_vals == 'No Platform', 'red', 'blue') # 修正reactive对象调用,添加括号 data <- count_platform()[,c('PLATFORM', 'Population')] dat <- datatable(data, selection = list(mode = 'single', target = 'cell'), options = list(rowCallback = JS("function(r,d) {$(r).attr('height', '15px')}")), # 修正Input ID的引号问题 callback = JS(gsub("\n", "", paste0("table.on('click.dt', 'td', function() { var row_=table.cell(this).index().row; var col=table.cell(this).index().column; var rnd= Math.random(); var data = [row_, col, rnd]; Shiny.onInputChange('", row_name, "', data); });"))) ) %>% formatStyle('PLATFORM', target = 'row', backgroundColor = styleEqual(my_vals, my_colors)) return(dat) }
额外排查建议
如果修正后仍有问题,可以打开浏览器的开发者工具(F12)查看Console面板,里面会显示前端JS的错误信息,这是排查Shiny静默崩溃问题的关键手段——很多时候R控制台无报错,但前端JS已经抛出了致命错误。
内容的提问来源于stack exchange,提问作者Skywind555

