首页 > 解决方案 > ShinyAction 按钮关闭应用程序,但绕过 session$onSessionEnded

问题描述

目前,我的功能可以启动闪亮的应用程序,获取用户输入,一旦人关闭闪亮的窗口就保存到全局变量。

我想添加 ActionButton 来关闭闪亮而不是人不得不关闭窗口

ActionButton 关闭闪亮 --- 但它绕过了代码session$onSessionEnded

运行 Shiny 终端后显示它扫描了调色板的值,但cherrypickedpalette 的全局变量为 NULL

> CherryPickPalette("BiryaniRice","Kulfi","Haveli2")

Listening on http://127.0.0.1:5345
Read 8 items
> cherrypickedpalette
NULL

这是整个 R 脚本

调用函数

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)
        })
      }
    )
    )
  }
}

标签: rshinyaction-button

解决方案


使用 github 代码,我现在可以重现您的应用程序。似乎onSessionEnded被调用了,因为文件被写入磁盘并且也cat被调用了。所以我认为问题不存在。不知何故,cherrypickedpalette <<-没有分配给全局环境。

但我不明白为什么你必须将结果写入磁盘然后再次扫描它们以获取值?这是出于特定原因吗?

assign我能够使用onSessionEnded 函数将颜色分配给全局环境。

尝试使用此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 关闭应用程序或关闭窗口,颜色应存储在变量中cherrypickedpalette

library(shiny)
CherryPickPalette("BiryaniRice","Kulfi","Haveli2")
cherrypickedpalette

更新1:

您也可以省略整个onSessionEnded过程并将变量写入observeEvent函数内部的全局环境。

删除 session 函数并将 observeEvent 替换为:

    observeEvent(input$action, {
      cherrypickedpalette <<- paste(isolate(outputdata())," ")
      stopApp()
    })

更新2:

所以 onSessionEnded 有效,问题实际上出在scan函数上。您似乎无法使用该功能直接写入全局环境。但是您可以使用它来存储值并在下一行中将此值分配给 glob.env。如果需要将值存储到磁盘,则使用以下几行它也应该可以工作。

      cherrypickedpalette <- scan(file=colorfile," ")
      cl <<- cherrypickedpalette

推荐阅读