如何在R Shiny中使用action按钮实现表格显示隐藏及修改值留存
问题背景
我写了一个简易Shiny App,在模态对话框内生成了用户输入矩阵:
- 点击
Modify按钮可调出默认用户输入表,支持修改默认值、增删输入列 - 点击
Show按钮可在主页面展示table2,点击Hide按钮可隐藏该表格,模态框中的table1为临时测试用途,后续可删除 - 点击
Reset按钮可将表格恢复为默认值
现有问题
Show和Hide按钮仅能生效一次- 修改输入表后,再次点击
Modify会调出默认表而非最新修改后的表格
需求
- 点击
Show和Hide可反复对最新修改的表格执行显示、隐藏操作,也可使用shinyjs的toggle函数将两个按钮合并为单个显示/隐藏按钮 - 应用首次启动时点击
Modify调出默认表,后续点击Modify则调出最新修改后的表格 - 未修改表格时点击
Show直接调出默认表
原始MWE代码
library(shiny) library(shinyMatrix) library(shinyjs) matrix3Input <- function(x){ matrixInput(x, label = 'Series terms:', value = matrix(c(1,24,0,1),4,1,dimnames=list(c("A","B","C","D"),NULL)), rows = list(extend = FALSE,names = TRUE), cols = list(extend = TRUE,names = TRUE,editableNames = TRUE,delete = TRUE), class = "numeric") # close matrix input } # close function ui <- fluidPage( useShinyjs(), titlePanel("Inputs"), fluidRow(actionButton("modify","Modify"), actionButton("show","Show"), actionButton("hide","Hide"), actionButton("reset","Reset"), tableOutput("table2") ) # close fluid row ) # close fluid page server <- function(input, output, session) { observeEvent(input$modify,{showModal(modalDialog( matrix3Input("matrix"), tableOutput("table1")) )}) output$table1 <- renderTable(input$matrix, rownames = TRUE) observeEvent(input$show,{ tableOutput("table2") output$table2 <- renderTable(input$matrix, rownames = TRUE) }) observeEvent(input$hide,{hide("table2")}) observeEvent(input$reset,{ tableOutput("table2") output$table2 <- renderTable(input$matrix, rownames = TRUE) }) } # close server shinyApp(ui, server)
修改后代码
library(shiny) library(shinyMatrix) library(shinyjs) # 定义默认矩阵,方便复用 default_mat <- matrix(c(1,24,0,1),4,1,dimnames=list(c("A","B","C","D"),NULL)) matrix3Input <- function(x, init_val = default_mat){ matrixInput(x, label = 'Series terms:', value = init_val, rows = list(extend = FALSE,names = TRUE), cols = list(extend = TRUE,names = TRUE,editableNames = TRUE,delete = TRUE), class = "numeric") } ui <- fluidPage( useShinyjs(), titlePanel("Inputs"), fluidRow( actionButton("modify","Modify"), actionButton("show","Show"), actionButton("hide","Hide"), # 如果要换成单个切换按钮,替换上面两个按钮为下面这行即可: # actionButton("toggle", "显示/隐藏"), actionButton("reset","Reset"), tableOutput("table2") ) ) server <- function(input, output, session) { # 用响应式值存储最新的矩阵数据,持久化修改结果 rv <- reactiveValues(my_matrix = default_mat) # 监听模态框内的矩阵修改,实时更新响应式值 observeEvent(input$matrix, { rv$my_matrix <- input$matrix }, ignoreInit = TRUE) # 点击Modify打开模态框时,加载当前最新的矩阵值 observeEvent(input$modify,{ showModal(modalDialog( matrix3Input("matrix", init_val = rv$my_matrix), tableOutput("table1") )) # 更新矩阵输入组件的值为最新的修改结果 updateMatrixInput(session, "matrix", value = rv$my_matrix) }) output$table1 <- renderTable(input$matrix, rownames = TRUE) # table2只渲染一次,依赖响应式值自动更新内容 output$table2 <- renderTable(rv$my_matrix, rownames = TRUE) # 点击Show直接显示表格,内容会自动同步最新值 observeEvent(input$show,{ show("table2") }) # 点击Hide隐藏表格 observeEvent(input$hide,{ hide("table2") }) # 如果用单个切换按钮,替换上面两个observeEvent为下面这行: # observeEvent(input$toggle, {toggle("table2")}) # 点击Reset恢复为默认矩阵 observeEvent(input$reset,{ rv$my_matrix <- default_mat # 如果当前模态框打开,同时更新模态框内的输入值 if(!is.null(input$matrix)){ updateMatrixInput(session, "matrix", value = default_mat) } show("table2") # 按需保留,不需要的话可以删除 }) } shinyApp(ui, server)
修改说明
- 新增响应式变量存储最新矩阵数据,实现修改结果的持久化,解决重复打开
Modify模态框重置为默认值的问题 table2仅定义一次渲染逻辑,依赖响应式值自动同步最新内容,不需要每次点击Show重复定义输出,解决Show仅生效一次的问题- 显示/隐藏逻辑直接调用
shinyjs的show/hide方法,无需重复定义输出,支持反复操作 - 重置逻辑直接修改响应式值,同时同步更新模态框内的输入组件,保证所有位置的数据一致
内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072
相关产品推荐
相关产品推荐

