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

修改shinyDirChoose的roots添加自定义目录后选择时报错求助

解决shinyDirChoose动态添加roots后path must not have missing values错误

问题根源

当你动态更新roots后,之前input$dir1存储的目录选择结构是基于旧roots的,用新roots去解析旧的input$dir1会触发解析错误;同时重复调用shinyDirChoose初始化目录选择器,会导致新旧状态冲突,进一步引发path缺失值的报错。

修复方案

  1. 仅初始化一次shinyDirChoose,直接传入响应式的roots,让选择器自动响应roots的更新
  2. 在解析目录路径时添加错误捕获,避免旧的input值触发解析报错
  3. 优化路径添加逻辑,确保仅在解析出有效路径时才更新roots

修改后的代码

library(shiny)
library(shinyFiles)
library(fs)

ui <- fluidPage(
  titlePanel("Add Volume to Roots in Shiny"),
  shinyDirButton("dir1", "Select Directory 1", "Please select a directory"),
  verbatimTextOutput("roots_info")
)

server <- function(input, output, session) {
  
  # Initial roots definition
  roots <- reactiveVal(c(
    home = fs::path_home(),
    output = paste0(fs::path_home(), "/Eclipse")
  ))
  
  # Show the current roots information
  output$roots_info <- renderPrint({ roots() })
  
  # 仅初始化一次shinyDirChoose,传入响应式roots
  shinyDirChoose(input, "dir1", roots = roots(), session = session)

  # Handle the directory selection with error handling
  observeEvent(input$dir1, {
    # 用tryCatch捕获解析错误,避免报错中断程序
    dir1 <- tryCatch(
      parseDirPath(roots(), input$dir1),
      error = function(e) NULL
    )
    
    if (!is.null(dir1) && !anyNA(dir1) && length(dir1) > 0) {
      new_roots <- roots()
      # 避免重复添加相同路径
      if (!dir1 %in% new_roots) {
        new_roots["custom"] <- dir1
        roots(new_roots)    
      }
    }
  })
   
}

shinyApp(ui, server)

关键修改说明

  • 移除了包裹shinyDirChoose的observe,改为直接在server顶层初始化,利用roots的响应式特性让选择器自动更新可访问目录
  • 用tryCatch包裹parseDirPath,当旧input值无法用新roots解析时,返回NULL,避免触发报错
  • 添加了重复路径判断,防止多次添加同一个目录到roots中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:21:13