我有一个复杂的Shiny应用程序。我有一个selectize
输出对象selectTest
,其值由被动对象isTestReady
读取。 isTestReady
评估selectTest
是否满足某些条件。然后将isTestReady
用作各种块作为门。我已将selectTest
设置为outputOptions(suspendWhenHidden = F, priority 999)
,以确保它立即启动并运行。
在运行时,我注意到selectTest
的块首先被执行。在此之后运行isTestReady
时,它仍会将selectTest
的值读取为NULL,而不是在第一个块中分配给selectTest
的任何值。在返回重新评估isTestReady
之前,Shiny会经历许多其他模块。在重新评估之后,再次调用其他块,现在它们运行良好。
这是预期的行为吗?如果是这样,关于如何使我的场景按照我描述的方式发挥的任何想法?
示例 -
library(shiny)
library(shinydashboard)
# Setup Shiny app UI components -------------------------------------------
ui <- dashboardPage(
dashboardHeader(),
## Sidebar content
dashboardSidebar(
sidebarMenu(
uiOutput('someelement'),
textOutput('temp2')
)
),
dashboardBody( )
)
# Setup Shiny app back-end components -------------------------------------
server <- function(input, output) {
output[['someelement']] = renderUI({
selectizeInput(
inputId = 'someelement',
choices = letters,
selected = letters[1],
label = 'Custom Functions',
multiple = F
)
})
outputOptions(
output,
'someelement',
suspendWhenHidden = F
)
temp = reactive({
print('?')
input[['someelement']]
})
observe({
print('!')
print(temp())
})
output[['temp2']] = renderText({
print('!!')
print(temp())
'-'
})
}
# Render Shiny app --------------------------------------------------------
shinyApp(ui, server)
输出到上述应用程序的控制台的日志如下所示 -
[1] "!"
[1] "?"
NULL
[1] "!!"
NULL
[1] "!"
[1] "?"
[1] "a"
[1] "!!"
[1] "a"
有什么办法可以避免那个NULL?在我的应用中,有很多块寻找temp()
,所有这些块都在temp()
之前运行。
答案 0 :(得分:0)
尝试使用observe()和reactiveValues(),查看this question的已接受答案。 reactive()是懒惰的。
我编辑了您的问题,因此文字中的变量名称与您的代码相匹配。但我可能会想念你。像这样的东西?
library(shiny)
library(shinydashboard)
# Setup Shiny app UI components -------------------------------------------
ui <- dashboardPage(
dashboardHeader(),
## Sidebar content
dashboardSidebar(
sidebarMenu(
uiOutput('ui_selectTest')
)
),
dashboardBody( )
)
# Setup Shiny app back-end components -------------------------------------
server <- function(input, output) {
rv<- reactiveValues()
output$ui_selectTest = renderUI({
selectizeInput(
inputId = 'selectTest',
choices = letters,
selected = letters[1],
label = 'Custom Functions',
multiple = F
)
})
observe(
if(!is.null(input$selectTest)) {
#check select test
rv$testReady <- input$selectTest
}
)
observeEvent(rv$testReady,{
print( rv$testReady )
})
}
shinyApp(ui, server)
答案 1 :(得分:0)
只需在每个反应块中使用validate
即可检查所有需要的输入和条件。您的服务器功能将看起来像这样
server <- function(input, output) {
output[['someelement']] = renderUI({
selectizeInput(
inputId = 'someelement',
choices = letters,
selected = letters[1],
label = 'Custom Functions',
multiple = F
)
})
outputOptions(
output,
'someelement',
suspendWhenHidden = F
)
temp = reactive({
#check if someelement is a valid input
validate(need(input[['someelement']] %in% letters, "need input"))
print('?')
input[['someelement']]
})
observe({
#check if tmp() has already been evaluated
validate(need(temp(), "need tmp"))
print('!')
print(temp())
})
output[['temp2']] = renderText({
validate(need(temp(), "need tmp"))
print('!!')
print(temp())
'-'
})
}