ShinyAction 按钮关闭应用程序,但绕过 session$onSessionEnded
ShinyAction Button Closes App, but Bypasses session$onSessionEnded
目前,我有启动 shiny 应用程序、获取用户输入、在用户关闭 shiny 后保存到全局变量的功能 window。
我想添加 ActionButton 来关闭 shiny 而不是必须关闭的人 window
ActionButton 闪亮关闭 --- 但它绕过了 session$onSessionEnded
中的代码
在 运行 Shiny 终端显示它扫描了调色板的值,但 cherrypickedpalette 的全局变量为 NULL
> CherryPickPalette("BiryaniRice","Kulfi","Haveli2")
Listening on http://127.0.0.1:5345
Read 8 items
> cherrypickedpalette
NULL
调用函数
CherryPickPalette <- function (name, name2=NULL, name3=NULL){
#snipped code#
cherrypickedpalette <- CustomPal(new_pal)
#snipped code#
}
闪亮的功能
CustomPal <- function(new_pal){
if (interactive()){
#snipped code#
}
cherrypickedpalette <- runApp(list(
#snipped code#
mainPanel(
h5('Your Cherry-Picked Palette',style = "font-weight: bold;"),
fluidRow(column(12,verbatimTextOutput("col"))),
actionButton("action", label = "I'm Done")
)
),
server = function(input,output,session){
outputdata<- reactive({
input$col
})
output$col <- {
renderPrint(outputdata())
}
#Code to detect closing button
observe({
if (input$action > 0)
stopApp()
})
#Code to detect closing button
session$onSessionEnded(function(){
message <- paste(isolate(outputdata())," ")
cat(message,file=colorfile, append=TRUE)
cherrypickedpalette <<- scan(file=colorfile," ")
stopApp(cherrypickedpalette)
file.remove(colorfile)
})
}
)
)
}
}
使用 github 代码,我现在可以重现您的应用程序。似乎 onSessionEnded
被调用,因为文件被写入磁盘并且 cat
被调用。所以我不认为问题在那里。不知何故 cherrypickedpalette <<-
没有分配给全局环境。
但是我不明白为什么要把结果写到磁盘然后再扫描得到值?这是出于特定原因吗?
我能够使用 onSessionEnded 函数中的 assign
将颜色分配给全局环境。
尝试改用此 CustomPal
函数:
CustomPal <- function(new_pal){
if (interactive()){
cherrypickedpalette <- runApp(list(
ui = {fluidPage(
titlePanel("Cherry Pick Your Own Palette!"),
sidebarPanel (hr(),
selectInput('col', 'Options', new_pal, multiple=TRUE, selectize=FALSE, size = 15)
),
mainPanel(
h5('Your Cherry-Picked Palette',style = "font-weight: bold;"),
fluidRow(column(12,verbatimTextOutput("col"))),
actionButton("action", label = "I'm Done")
)
)},
server = function(input,output,session) {
outputdata<- reactive({
input$col
})
output$col <- {
renderPrint(outputdata())
}
observeEvent(input$action, {
stopApp()
})
session$onSessionEnded(function(){
message <- paste(isolate(outputdata())," ")
print(paste("Message: ", message))
assign("cherrypickedpalette", message, pos = .GlobalEnv)
stopApp(cherrypickedpalette)
})
}
)
)
}
}
加载所有功能后,调用 shinyApp,选择颜色,通过 actionButton 或关闭 window 关闭应用程序,颜色应存储在变量 cherrypickedpalette
.
library(shiny)
CherryPickPalette("BiryaniRice","Kulfi","Haveli2")
cherrypickedpalette
更新 1:
也可以省略整个onSessionEnded
过程,在observeEvent
函数中将变量写入全局环境。
删除会话函数并将observeEvent替换为:
observeEvent(input$action, {
cherrypickedpalette <<- paste(isolate(outputdata())," ")
stopApp()
})
更新 2:
所以 onSessionEnded 有效,问题实际上出在 scan
函数上。似乎您不能使用该功能直接写入全局环境。但是您可以使用它来存储值,并在下一行中将此值分配给 glob.env。如果需要将值存储到磁盘,则使用以下行它也应该可以工作。
cherrypickedpalette <- scan(file=colorfile," ")
cl <<- cherrypickedpalette
目前,我有启动 shiny 应用程序、获取用户输入、在用户关闭 shiny 后保存到全局变量的功能 window。
我想添加 ActionButton 来关闭 shiny 而不是必须关闭的人 window
ActionButton 闪亮关闭 --- 但它绕过了 session$onSessionEnded
在 运行 Shiny 终端显示它扫描了调色板的值,但 cherrypickedpalette 的全局变量为 NULL
> CherryPickPalette("BiryaniRice","Kulfi","Haveli2")
Listening on http://127.0.0.1:5345
Read 8 items
> cherrypickedpalette
NULL
调用函数
CherryPickPalette <- function (name, name2=NULL, name3=NULL){
#snipped code#
cherrypickedpalette <- CustomPal(new_pal)
#snipped code#
}
闪亮的功能
CustomPal <- function(new_pal){
if (interactive()){
#snipped code#
}
cherrypickedpalette <- runApp(list(
#snipped code#
mainPanel(
h5('Your Cherry-Picked Palette',style = "font-weight: bold;"),
fluidRow(column(12,verbatimTextOutput("col"))),
actionButton("action", label = "I'm Done")
)
),
server = function(input,output,session){
outputdata<- reactive({
input$col
})
output$col <- {
renderPrint(outputdata())
}
#Code to detect closing button
observe({
if (input$action > 0)
stopApp()
})
#Code to detect closing button
session$onSessionEnded(function(){
message <- paste(isolate(outputdata())," ")
cat(message,file=colorfile, append=TRUE)
cherrypickedpalette <<- scan(file=colorfile," ")
stopApp(cherrypickedpalette)
file.remove(colorfile)
})
}
)
)
}
}
使用 github 代码,我现在可以重现您的应用程序。似乎 onSessionEnded
被调用,因为文件被写入磁盘并且 cat
被调用。所以我不认为问题在那里。不知何故 cherrypickedpalette <<-
没有分配给全局环境。
但是我不明白为什么要把结果写到磁盘然后再扫描得到值?这是出于特定原因吗?
我能够使用 onSessionEnded 函数中的 assign
将颜色分配给全局环境。
尝试改用此 CustomPal
函数:
CustomPal <- function(new_pal){
if (interactive()){
cherrypickedpalette <- runApp(list(
ui = {fluidPage(
titlePanel("Cherry Pick Your Own Palette!"),
sidebarPanel (hr(),
selectInput('col', 'Options', new_pal, multiple=TRUE, selectize=FALSE, size = 15)
),
mainPanel(
h5('Your Cherry-Picked Palette',style = "font-weight: bold;"),
fluidRow(column(12,verbatimTextOutput("col"))),
actionButton("action", label = "I'm Done")
)
)},
server = function(input,output,session) {
outputdata<- reactive({
input$col
})
output$col <- {
renderPrint(outputdata())
}
observeEvent(input$action, {
stopApp()
})
session$onSessionEnded(function(){
message <- paste(isolate(outputdata())," ")
print(paste("Message: ", message))
assign("cherrypickedpalette", message, pos = .GlobalEnv)
stopApp(cherrypickedpalette)
})
}
)
)
}
}
加载所有功能后,调用 shinyApp,选择颜色,通过 actionButton 或关闭 window 关闭应用程序,颜色应存储在变量 cherrypickedpalette
.
library(shiny)
CherryPickPalette("BiryaniRice","Kulfi","Haveli2")
cherrypickedpalette
更新 1:
也可以省略整个onSessionEnded
过程,在observeEvent
函数中将变量写入全局环境。
删除会话函数并将observeEvent替换为:
observeEvent(input$action, {
cherrypickedpalette <<- paste(isolate(outputdata())," ")
stopApp()
})
更新 2:
所以 onSessionEnded 有效,问题实际上出在 scan
函数上。似乎您不能使用该功能直接写入全局环境。但是您可以使用它来存储值,并在下一行中将此值分配给 glob.env。如果需要将值存储到磁盘,则使用以下行它也应该可以工作。
cherrypickedpalette <- scan(file=colorfile," ")
cl <<- cherrypickedpalette