如何在Shiny模块化应用中获取argonTabSet选中argonTab的tabName值
模块化下获取argonTabSet选中tabName的实现
你给argonTabSet的id包裹ns()后无法读取值是使用方法问题,正确操作如下:
- 在
renderUI内定义argonTabSet时,id参数用session$ns("t_brnd")包裹 - 模块内直接通过
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
相关产品推荐
相关产品推荐

