嵌套模块中输入的反应性
Reactivity of input in nested modules
我正在尝试用 n=4 个不同的 tabPanels 做一个闪亮的应用程序 (NavbarPage)。所有面板都将具有(几乎)相同的结构,因此我决定为此使用模块。为了使代码可重用于其他应用程序,我将所有变量放入 global.R.
我的问题:
我想在每个站点的顶部都有一个选项面板。有些选项对于每个 tabPanel 是相同的,有些则不同。在我的“optionServer”模块中,我想将所有输入存储到全局 reactiveValues 变量“optionSel”中。实际上,可以很容易地通过 renderPrint() 访问输入变量 [意味着它不应该是打字错误],但我找不到将输入值存储为 reactive(input$...)等..
请看我的代码,非常感谢你的帮助
#global.R
library(shiny)
source('module/functmodul.R')
label<-c("Label1", "Label2","Label3", "Label4")
tabs<-c("tab1","tab2","tab3", "tab4")
optionset<-list(c('opt11'=1,'opt12'=2,'opt13'=3),
c('opt21'=1,'opt22'=2,'opt23'=3),
c(TRUE,FALSE),
c('opt41'=1, 'opt42'=2, 'opt43'=3,'opt44'=4))
option<-data.frame('id'=c('id11', 'id12','id13', 'id14'),
'label'=c("choice1: ", "choice2: ", "choice3", "choice4"),
'defval'=c(1,1,FALSE,1))
#checkboxGroupInput=1,radioButtons=2,checkboxInput=3
opttab<-data.frame(
c(1,2,3,0),
c(2,0,0,0),
c(0,0,0,0),
c(0,0,0,1)
)
optionSel<-reactiveValues()
#ui.R
shinyUI(
do.call(navbarPage,
c(
title = 'test',
lapply(
1:length(tabs),
function(i) {
tabPanel(
label[i], id=tabs[i],
fluidRow(
column(h4(label[i]),width=9),
column(img(src="logo.jpg", height="100pt", style=""), width=3)),
optionUI(i),
detailUI(i)
)
}
)
)
)
)
#server.R
shinyServer(function(input, output) {
lapply(
1:length(tabs),
function(i){
optionServer(i)
detailServer(i)
}
)
})
模块代码module/functmodul.R
optionUI <- function(id) {
ns <- NS(id)
a<-as.integer(id)
tagList(
verbatimTextOutput(ns('testfx1')),
lapply(1:nrow(option),function(d){
getInput(a,d)
})
)
}
getInput<-function(id,d){
ns<-NS(id)
c<-opttab[id][,1][d] # c bestimmt die Art des Inputfelds (checkboxGroupI, radioButtons oder checkboxInput)
switch(c,
'1' = {checkboxGroupInput(ns(option$id[d]), option$label[d], optionset[[d]], selected = c(option$defval[d]), inline = TRUE)},
'2' = {radioButtons(ns(option$id[d]), option$label[d], optionset[[d]], selected=option$defval[d], inline=TRUE)},
'3' = {checkboxInput(ns(option$id[d]), option$label[d])},
default = {}
)
}
optionServer <- function(id) {
moduleServer(
id,
function(input, output, session) {
for(z in 1:nrow(option)){
c<-opttab[id][,1][z]
if (c!=0){
optionSel[[paste0(option$id[z],tabs[id])]]<<-reactive({input[[option$id[z]]]}) #not working
}
}
output$testfx1<-renderPrint(input[[option$id[1]]]) #working
}
)
}
detailUI<-function(id){
ns <- NS(id)
tagList(
verbatimTextOutput(ns('testfx2'))
)
}
detailServer <- function(id) {
moduleServer(
id,
function(input, output, session) {
output$testfx2<-renderPrint(optionSel[[paste0(option$id[z],tabs[id])]]) #not working
}
)
}
如果有人感兴趣,我找到了一个解决方案,即使它看起来不是很优雅,也能使程序运行。
我把module/functmodul.R // optionServer改成如下
optionServer <- function(id) {
moduleServer(
id,
function(input, output, session) {
a<-as.numeric(id)
opt1<-reactive({input[[option$id[1]]]})
opt2<-reactive({input[[option$id[2]]]})
opt3<-reactive({input[[option$id[3]]]})
opt4<-reactive({input[[option$id[4]]]})
return(
list(
opt1,
opt2,
opt3,
opt4
)
)
}
)
}
然后我进入了 Server.R
optionSel<-optionServer(i)
而不是仅调用函数...
所以我可以在 server.R 中使用 optionSel[[1]], optionSel[[2]],...,optionSel[[5]] 来调用 return 值
我正在尝试用 n=4 个不同的 tabPanels 做一个闪亮的应用程序 (NavbarPage)。所有面板都将具有(几乎)相同的结构,因此我决定为此使用模块。为了使代码可重用于其他应用程序,我将所有变量放入 global.R.
我的问题: 我想在每个站点的顶部都有一个选项面板。有些选项对于每个 tabPanel 是相同的,有些则不同。在我的“optionServer”模块中,我想将所有输入存储到全局 reactiveValues 变量“optionSel”中。实际上,可以很容易地通过 renderPrint() 访问输入变量 [意味着它不应该是打字错误],但我找不到将输入值存储为 reactive(input$...)等..
请看我的代码,非常感谢你的帮助
#global.R
library(shiny)
source('module/functmodul.R')
label<-c("Label1", "Label2","Label3", "Label4")
tabs<-c("tab1","tab2","tab3", "tab4")
optionset<-list(c('opt11'=1,'opt12'=2,'opt13'=3),
c('opt21'=1,'opt22'=2,'opt23'=3),
c(TRUE,FALSE),
c('opt41'=1, 'opt42'=2, 'opt43'=3,'opt44'=4))
option<-data.frame('id'=c('id11', 'id12','id13', 'id14'),
'label'=c("choice1: ", "choice2: ", "choice3", "choice4"),
'defval'=c(1,1,FALSE,1))
#checkboxGroupInput=1,radioButtons=2,checkboxInput=3
opttab<-data.frame(
c(1,2,3,0),
c(2,0,0,0),
c(0,0,0,0),
c(0,0,0,1)
)
optionSel<-reactiveValues()
#ui.R
shinyUI(
do.call(navbarPage,
c(
title = 'test',
lapply(
1:length(tabs),
function(i) {
tabPanel(
label[i], id=tabs[i],
fluidRow(
column(h4(label[i]),width=9),
column(img(src="logo.jpg", height="100pt", style=""), width=3)),
optionUI(i),
detailUI(i)
)
}
)
)
)
)
#server.R
shinyServer(function(input, output) {
lapply(
1:length(tabs),
function(i){
optionServer(i)
detailServer(i)
}
)
})
模块代码module/functmodul.R
optionUI <- function(id) {
ns <- NS(id)
a<-as.integer(id)
tagList(
verbatimTextOutput(ns('testfx1')),
lapply(1:nrow(option),function(d){
getInput(a,d)
})
)
}
getInput<-function(id,d){
ns<-NS(id)
c<-opttab[id][,1][d] # c bestimmt die Art des Inputfelds (checkboxGroupI, radioButtons oder checkboxInput)
switch(c,
'1' = {checkboxGroupInput(ns(option$id[d]), option$label[d], optionset[[d]], selected = c(option$defval[d]), inline = TRUE)},
'2' = {radioButtons(ns(option$id[d]), option$label[d], optionset[[d]], selected=option$defval[d], inline=TRUE)},
'3' = {checkboxInput(ns(option$id[d]), option$label[d])},
default = {}
)
}
optionServer <- function(id) {
moduleServer(
id,
function(input, output, session) {
for(z in 1:nrow(option)){
c<-opttab[id][,1][z]
if (c!=0){
optionSel[[paste0(option$id[z],tabs[id])]]<<-reactive({input[[option$id[z]]]}) #not working
}
}
output$testfx1<-renderPrint(input[[option$id[1]]]) #working
}
)
}
detailUI<-function(id){
ns <- NS(id)
tagList(
verbatimTextOutput(ns('testfx2'))
)
}
detailServer <- function(id) {
moduleServer(
id,
function(input, output, session) {
output$testfx2<-renderPrint(optionSel[[paste0(option$id[z],tabs[id])]]) #not working
}
)
}
如果有人感兴趣,我找到了一个解决方案,即使它看起来不是很优雅,也能使程序运行。
我把module/functmodul.R // optionServer改成如下
optionServer <- function(id) {
moduleServer(
id,
function(input, output, session) {
a<-as.numeric(id)
opt1<-reactive({input[[option$id[1]]]})
opt2<-reactive({input[[option$id[2]]]})
opt3<-reactive({input[[option$id[3]]]})
opt4<-reactive({input[[option$id[4]]]})
return(
list(
opt1,
opt2,
opt3,
opt4
)
)
}
)
}
然后我进入了 Server.R
optionSel<-optionServer(i)
而不是仅调用函数... 所以我可以在 server.R 中使用 optionSel[[1]], optionSel[[2]],...,optionSel[[5]] 来调用 return 值