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

如何在Shiny模块化应用中获取argonTabSet选中argonTab的tabName值

模块化下获取argonTabSet选中tabName的实现

你给argonTabSet的id包裹ns()后无法读取值是使用方法问题,正确操作如下:

  1. 在renderUI内定义argonTabSet时,id参数用session$ns("t_brnd")包裹
  2. 模块内直接通过input$t_brnd即可读取当前选中的tabName,无需额外加命名空间前缀,shiny模块会自动处理映射

修正后的最小示例代码:

library(shiny)
library(argonR)
library(argonDash)

mod_price_ov_UI <- function(id) {
  ns <- NS(id)
  tagList(
    uiOutput(ns('ot_cat_brnd_rtlr'))
    , uiOutput(ns('selected_tab'))
  )
}

mod_price_ov <- function(id){
  moduleServer(id,function(input, output, session) {
    output$ot_cat_brnd_rtlr <- renderUI({
      ns <- session$ns
      brands <- paste0('brand_', 1:4)
      tagList(
        do.call(argonTabSet, c(
          id = ns('t_brnd'), 
          lapply(1:length(brands), function(i) {
            argonTab(
              tabName = brands[i],
              active  = ifelse(i == 1, T, F)
            )
          })
        ))
      )
    })
    
    output$selected_tab <- renderUI({
      input$t_brnd
    })
  })
}

shiny::shinyApp(
  ui = argonDashPage(
    body = argonDashBody(mod_price_ov_UI('ov'))
  ),
  server = function(input, output, session) {
    mod_price_ov('ov')
  }
)

单选按钮仅最后一个生效的修复

该问题是R语言循环的延迟求值特性导致的:lapply循环内的迭代变量会在所有回调触发时统一取最后一次迭代的取值,导致前3个标签页的单选按钮判断逻辑实际都指向最后一个品牌。
修复方案是用local()包裹每次循环的逻辑,为每个迭代创建独立作用域,固定当前迭代对应的品牌值,同时建议用observeEvent绑定单个单选按钮的变更事件,避免不必要的触发。

修复后的完整业务代码:

library(shiny)
library(argonR)
library(argonDash)
library(magrittr)
library(tidyverse)
library(DT)

set.seed(1234)

mod_price_ov_UI <- function(id) {
  ns <- NS(id)
  tagList(
    tableOutput(ns('category_tally')),
    uiOutput(ns('ot_cat_brnd_rtlr')))
}

mod_price_ov <- function(id){
  moduleServer(
    id,
    function(input, output, session) {
      
      toy_rtcv <- reactive({tibble(
        category   = sample(paste0('cat_'  , 1:3), 100, replace = T)
        , brand    = sample(paste0('brand_', 1:4), 100, replace = T)
      )})
      
      output$category_tally <- renderTable({toy_rtcv() %>% summarise(total = n())})
      
      output$ot_cat_brnd_rtlr <- renderUI({
        ns <- session$ns
        brands <- toy_rtcv() %>% select(brand) %>% distinct() %>% pull(brand)
        tagList(
          do.call(argonTabSet, c(id= ns('t_brnd'), lapply(1:length(brands), function(i) {
            argonTab(
              tabName  = brands[i]
              , active = ifelse(i == 1, T, F)
              , radioButtons(ns(paste0('rdio_cat_brnd_rtlr', brands[i]))
                             , 'Brand Stats'
                             , choices = c('YES', 'NO')
                             , selected = 'NO'
                             , inline = T
              )
              , dataTableOutput(ns(paste0('ot_retailer_', brands[i])))
            )}))))})
      
      observe({
        brands <- toy_rtcv() %>% select(brand) %>% distinct() %>% pull(brand)
        lapply(1:length(brands), function(i) {
          output[[paste0('ot_retailer_', brands[i])]]  = renderDataTable({
            toy_rtcv() %>% 
              filter(brand == brands[i])
          })})})
      
      observe({
        brands <- toy_rtcv() %>% select(brand) %>% distinct() %>% pull(brand)
        lapply(1:length(brands), function(i){
          local({
            cur_i <- i
            cur_brand <- brands[cur_i]
            cur_rdio_id <- paste0('rdio_cat_brnd_rtlr', cur_brand)
            observeEvent(input[[cur_rdio_id]], {
              if(is.null(input[[cur_rdio_id]])) return(NULL)
              if(input[[cur_rdio_id]] == 'YES'){
                output$category_tally <- renderTable({
                  toy_rtcv() %>%
                    filter(brand == cur_brand) %>%
                    summarise(total = n())})
              } else {
                output$category_tally <- renderTable({
                  toy_rtcv() %>%
                    summarise(total = n())
                })
              }
            }, ignoreInit = TRUE)
          })
        })
      })
      
    })
}

shiny::shinyApp(
  ui = argonDashPage(
    body = argonDashBody(mod_price_ov_UI('ov'))
  ),
  server = function(input, output, session) {mod_price_ov('ov')}
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:15:02