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

如何将Shiny浏览器时区值从UI传递至readTzServer模块并读取

问题诊断与解决方案

你的问题核心在于模块UI元素没有正确使用命名空间,导致client_time_zone_international这个输入项注册在了全局命名空间下,而模块的server函数只能访问自己命名空间内的输入。另外代码里还有一处语法错误需要修正,下面一步步来解决:

核心问题分析

在readTzUi中,你创建textInput时没有用ns()包裹ID:

textInput("client_time_zone_international", "Time zone international", value = "")

这会让这个输入项的ID直接是client_time_zone_international(全局命名空间),而模块的readTzServer只能访问以模块ID(这里是readtz1)为前缀的命名空间内的输入(比如readtz1-button),所以自然拿不到全局的client_time_zone_international的值,而主server可以访问全局所有输入,所以能打印出值。

同时你的readTzServer里有一处语法错误:count observe({应该是observe({。

修正步骤

1. 给UI元素添加命名空间

把textInput的ID用ns()包裹,让它属于模块的命名空间:

textInput(ns("client_time_zone_international"), "Time zone international", value = "")

2. 调整JS代码适配命名空间

原来的JS选择器$("#client_time_zone_international")现在找不到元素了,因为元素ID变成了readtz1-client_time_zone_international(模块ID+原ID)。更可靠的方式是用Shiny.setInputValue直接给模块内的输入赋值,同时利用Shiny的命名空间机制:

tags$script(sprintf('
  $(function() {
    Shiny.setInputValue("%s", Intl.DateTimeFormat().resolvedOptions().timeZone);
  });
', ns("client_time_zone_international")))

这种方式直接用ns()生成正确的ID字符串传入JS,避免手动处理命名空间,更简洁可靠。

3. 修复server里的语法错误

把count observe({改成observe({。

完整修正后的代码

library(shiny)

readTzUi <- function(id, label = "readTz"){
  ns <- NS(id)
  fluidPage(
    # 用sprintf生成带正确命名空间的JS代码
    tags$script(sprintf('
      $(function() {
        Shiny.setInputValue("%s", Intl.DateTimeFormat().resolvedOptions().timeZone);
      });
    ', ns("client_time_zone_international"))),
    # 给textInput添加命名空间
    textInput(ns("client_time_zone_international"), "Time zone international", value = ""),
    tags$br(),
    actionButton(ns("button"), label = label),
    verbatimTextOutput(ns("but_out")),
    verbatimTextOutput(ns("out"))
  )
}

readTzServer <- function(id){
  moduleServer(
    id,
    function(input, output, session){
      # 现在可以正常获取时区值了
      observe(print(input$client_time_zone_international))
      
      count <- reactiveVal(0)
      
      observeEvent(input$button, {
        count(count() + 1)
      })
      
      output$but_out <- renderText({
        count()
      })
      
      # 修复语法错误
      observe({
        output$out <- renderText({
          "Hello"
        })
      })
    }
  )
}

ui <- fluidPage(
  readTzUi("readtz1", "Counter#2")
)

server <- function(input, output, session) {
  readTzServer("readtz1")
  
  observe(
    print(input$client_time_zone_international)
  )
}

shinyApp(ui, server)

验证效果

运行修正后的代码,你会发现readTzServer里的print(input$client_time_zone_international)能正常输出浏览器的时区值,主server也能正常输出,模块的其他功能(按钮计数、文本输出)也能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:54:56