使用馈送到模块 R Shiny 的无功值更新单选按钮
Update Radio buttons using a Reactive Value fed to a Module, R Shiny
我正在构建一个 shiny
应用程序,并且将在多个页面上具有相同的 radio button
输入,这将改变页面上显示的内容。我将这些单选按钮放在一个模块中,这样我就不必在多个地方重现该代码。它们都有一组静态的 choices
,但我希望它们在整个应用程序中都保持相同的 selected
值。这意味着您每次更改页面时,都会像以前一样 select 编辑相同的值。如果我在一个页面上 select A
,所有其他页面也会 A
select 编辑,直到我在任何其他页面上选择不同的选项。
到目前为止,我的任何尝试都没有成功。 似乎接近我正在寻找的东西,但我无法让它发挥作用。在下面的应用程序中,我觉得我应该能够向 modServer
函数传递一个反应值,该值会将关联的 radio buttons
更新为相同的 selected
值。如果我可以根据 input$tmp
进行此单个模块更新,我认为我应该能够在模块的多个迭代中复制它。
编辑: 更新代码。应用程序现在可以检查模块外部 input$tmp
的值本身和反应值。也在模块内作为输入以及新的无功值。
新问题:为什么将这些变量中的 none 显示为反应变量?这一定是 observeEvent
在 modServer
中不起作用的原因。 renderText
显示这些值正在更新,但不会触发 updateRadioGroupButtons
.
library(shiny)
library(shinyWidgets)
# UI module
modUI <- function(id){
ns <- NS(id)
tagList(
shinyWidgets::radioGroupButtons(
inputId = ns("radio"),
choices = c('A', 'B', 'C', 'D'),
selected = 'A'),
uiOutput(ns('modtest')),
uiOutput(ns('modtest2'))
)
}
# Server module
modServer <- function(id, .selected){
moduleServer( id, function(input, output, session){
ns <- session$ns
mod_rval <- reactive({ .selected() })
output$modtest <- renderText({
paste('mod_rval() is:', mod_rval(), 'and is reactive: ', is.reactive(mod_rval()))
})
output$modtest2 <- renderText({
paste('.selected() is:', .selected(), 'and is reactive: ', is.reactive(.selected()))
})
observeEvent(.selected(), {
shinyWidgets::updateRadioGroupButtons(
session,
inputId = ns("radio"),
choices = c('A', 'B', 'C', 'D'),
selected = .selected()
)
})
})
}
# APP
ui <- fluidPage(
selectInput('tmp', 'tmp : input value', choices = c('A','B','C','D')),
modUI(id='mod1'),
uiOutput('test'),
uiOutput('test2')
)
server <- function(input, output, session) {
# functioning.
rval <- reactive({input$tmp})
modServer(id = 'mod1', .selected = rval)
output$test <- renderText({
paste('rval() is: ', rval(), 'and is reactive: ', is.reactive(rval()))
})
output$test2 <- renderText({
paste('input$tmp is: ', input$tmp, 'and is reactive: ', is.reactive(input$tmp))
})
}
shinyApp(ui, server)
您在 updateRadioGroupButtons(...)
中不需要 ns
,并且您确实需要在不同的服务器模块中进行更新,因为一个正在影响另一个。试试这个
library(shiny)
library(shinyWidgets)
# UI module
modUI <- function(id){
ns <- NS(id)
shinyWidgets::radioGroupButtons(
inputId = ns("radio"),
choices = c('A', 'B', 'OK', 'Whatever'),
selected = 'A')
}
# Server module 1
modServe <- function(id){
moduleServer( id, function(input, output, session){
return(reactive(input$radio))
})
}
# Server module 2
modServer <- function(id, selected){
moduleServer( id, function(input, output, session){
observe({
print(selected())
shinyWidgets::updateRadioGroupButtons(
session,
inputId = "radio",
choices = c('A', 'B', 'C', 'D'),
selected = selected()
)
})
})
}
# APP
ui <- fluidPage(
modUI(id='mod1'),
modUI(id='mod2')
)
server <- function(input, output, session) {
m1 <- modServe("mod1")
m2 <- modServe("mod2")
modServer("mod2",m1)
modServer("mod1",m2)
}
shinyApp(ui, server)
我正在构建一个 shiny
应用程序,并且将在多个页面上具有相同的 radio button
输入,这将改变页面上显示的内容。我将这些单选按钮放在一个模块中,这样我就不必在多个地方重现该代码。它们都有一组静态的 choices
,但我希望它们在整个应用程序中都保持相同的 selected
值。这意味着您每次更改页面时,都会像以前一样 select 编辑相同的值。如果我在一个页面上 select A
,所有其他页面也会 A
select 编辑,直到我在任何其他页面上选择不同的选项。
到目前为止,我的任何尝试都没有成功。 modServer
函数传递一个反应值,该值会将关联的 radio buttons
更新为相同的 selected
值。如果我可以根据 input$tmp
进行此单个模块更新,我认为我应该能够在模块的多个迭代中复制它。
编辑: 更新代码。应用程序现在可以检查模块外部 input$tmp
的值本身和反应值。也在模块内作为输入以及新的无功值。
新问题:为什么将这些变量中的 none 显示为反应变量?这一定是 observeEvent
在 modServer
中不起作用的原因。 renderText
显示这些值正在更新,但不会触发 updateRadioGroupButtons
.
library(shiny)
library(shinyWidgets)
# UI module
modUI <- function(id){
ns <- NS(id)
tagList(
shinyWidgets::radioGroupButtons(
inputId = ns("radio"),
choices = c('A', 'B', 'C', 'D'),
selected = 'A'),
uiOutput(ns('modtest')),
uiOutput(ns('modtest2'))
)
}
# Server module
modServer <- function(id, .selected){
moduleServer( id, function(input, output, session){
ns <- session$ns
mod_rval <- reactive({ .selected() })
output$modtest <- renderText({
paste('mod_rval() is:', mod_rval(), 'and is reactive: ', is.reactive(mod_rval()))
})
output$modtest2 <- renderText({
paste('.selected() is:', .selected(), 'and is reactive: ', is.reactive(.selected()))
})
observeEvent(.selected(), {
shinyWidgets::updateRadioGroupButtons(
session,
inputId = ns("radio"),
choices = c('A', 'B', 'C', 'D'),
selected = .selected()
)
})
})
}
# APP
ui <- fluidPage(
selectInput('tmp', 'tmp : input value', choices = c('A','B','C','D')),
modUI(id='mod1'),
uiOutput('test'),
uiOutput('test2')
)
server <- function(input, output, session) {
# functioning.
rval <- reactive({input$tmp})
modServer(id = 'mod1', .selected = rval)
output$test <- renderText({
paste('rval() is: ', rval(), 'and is reactive: ', is.reactive(rval()))
})
output$test2 <- renderText({
paste('input$tmp is: ', input$tmp, 'and is reactive: ', is.reactive(input$tmp))
})
}
shinyApp(ui, server)
您在 updateRadioGroupButtons(...)
中不需要 ns
,并且您确实需要在不同的服务器模块中进行更新,因为一个正在影响另一个。试试这个
library(shiny)
library(shinyWidgets)
# UI module
modUI <- function(id){
ns <- NS(id)
shinyWidgets::radioGroupButtons(
inputId = ns("radio"),
choices = c('A', 'B', 'OK', 'Whatever'),
selected = 'A')
}
# Server module 1
modServe <- function(id){
moduleServer( id, function(input, output, session){
return(reactive(input$radio))
})
}
# Server module 2
modServer <- function(id, selected){
moduleServer( id, function(input, output, session){
observe({
print(selected())
shinyWidgets::updateRadioGroupButtons(
session,
inputId = "radio",
choices = c('A', 'B', 'C', 'D'),
selected = selected()
)
})
})
}
# APP
ui <- fluidPage(
modUI(id='mod1'),
modUI(id='mod2')
)
server <- function(input, output, session) {
m1 <- modServe("mod1")
m2 <- modServe("mod2")
modServer("mod2",m1)
modServer("mod1",m2)
}
shinyApp(ui, server)