【问题标题】:R shiny: isolate session variablesR闪亮:隔离会话变量
【发布时间】:2015-09-19 21:02:35
【问题描述】:

我正在尝试隔离包含会话值session$sendCustomMessage 的部分,以便在单击ActionButton 时发送消息。用户上传文件,然后ActionButton 变为可见。只有当按钮被点击时,我们才应该进入server.R的隔离部分。在此之后,完成一些计算,并将一个文件返回给用户。但是,我未能正确隔离,即使没有单击ActionButton,文件也会返回。这是我的应用程序:

服务器.R:

library(shiny)


shinyServer(function(input, output, session) {


  observe({

    inFile <- input$upload

    if (is.null(inFile))
      return(NULL)

    # Send message indicating that the file is now uploaded
    session$sendCustomMessage("upload_ready", list(fileSize=0))

    # Read the .csv file 
    df = readLines(inFile$datapath)

    # Isolate this section from the reactive context.
    # But this is executing even if the Action Button is not
    # clicked
    isolate({

      # Make this isolated section dependent on the start_proc ActionButton
      input$start_proc

      output$data_file <- downloadHandler(
        filename = function() {
          paste('probabilities-', Sys.Date(), '.txt', sep='')
        }
        ,
        content = function(file1) {
          writeLines(df, con = file1)
        }
      )

      # I think this is the problem, the session changes even if the
      # action button is not clicked, and this is why the code is going
      # into this section.
      session$sendCustomMessage("download_ready", list(fileSize=0))

    })

  })

})

ui.R

library(shiny)
library(shinyBS)

shinyUI(fixedPage(
  singleton(tags$head(HTML(
    '
    <script type="text/javascript">
    $(document).ready(function() {

    // disable download at startup. data_file is the id of the downloadButton

    $("#data_file").attr("disabled", "true").attr("onclick", "return false;");

    // Disable start_prob at the beginning
    $("#start_proc").hide();


    // When uploaded file is ready, give the option to start process
    Shiny.addCustomMessageHandler("upload_ready", function(message) {
    $("#start_proc").show();
    });  

    // When the start_proc button is clicked, hide the button and disable
    // 

    $("#start_proc").click(function(){
    $("#start_proc").hide();
    $("#upload").prop("disabled", true);
    });

    // Show the option to download the file when the download is ready.
    // Also hide the button stat_proc and reactivate the option to upload
    // a file.
    Shiny.addCustomMessageHandler("download_ready", function(message) {
    $("#upload").prop("disabled", false);
    $("#data_file").removeAttr("disabled").removeAttr("onclick").html(
    "<i class=\\"fa fa-download\\"></i>Download Ready");
    });
    })
    </script>
    '
  ))),
   fileInput("upload", ""),
   bsButton("start_proc", h5("Compute Probability\n"), size = "extra-small", style = "primary"),
   downloadButton("data_file"),
   helpText("Download will be available once the processing is completed.")
))

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    您的问题与会话变量完全无关。此处实际触发计算的唯一事件是input$upload。如果上传为空,则您的代码将点击以下几行

    if (is.null(inFile))
      return(NULL)
    

    一切都按预期进行。如果文件已上传,您的程序将到达隔离块。使用 isolate 括起来的任何变量都不会被视为依赖项,因此遵循部分代码根本没有任何影响,并且您在注释中所做的假设是完全错误的:

    isolate({
       # Make this isolated section dependent on the start_proc ActionButton
       input$start_proc
       ...
    })
    

    即使您将input$start_proc 放在isolate 块之外,您的代码也不会按预期工作,因为您根本没有检查是否已单击操作按钮。

    使您的代码工作的一种方法是将上传和下载逻辑分开,如下所示:

    shinyServer(function(input, output, session) {
        raw <- reactive({
            inFile <- input$upload
            if (is.null(inFile)) return()
            # Read the .csv file 
            readLines(inFile$datapath)
        })
    
        observe({
            if (is.null(raw())) return() # If input empty return
            # Send message indicating that the file is now uploaded
            session$sendCustomMessage("upload_ready", list(fileSize=0))
        })
    
        df <- eventReactive(
            input$start_proc, # Button clicked 
            {raw()} # Send data to download handler
        )
    
        observe({
            if (is.null(df())) return() # In "preprocessed" data empty return
    
            output$data_file <- downloadHandler(
                filename = function() {
                    paste('probabilities-', Sys.Date(), '.txt', sep='')
                },
                content = function(file1) {
                    writeLines(df(), con = file1)
                }
            )
            # And send meassage
            session$sendCustomMessage("download_ready", list(fileSize=0))
        })
    })
    

    【讨论】:

    • 分离事物的好主意。但是,点击按钮会不断增加,所以仅仅检查它是否等于 0 是不够的。
    • 如果你想支持多个上传,提取处理逻辑和按钮处理程序是有意义的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    • 2020-06-22
    • 2015-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多