2015-09-19 67 views
1

我試圖分離含有的會話值session$sendCustomMessage以便被點擊的ActionButton當我可以發送的消息的部分。用戶上傳文件,然後ActionButton變得可見。只有當按鈕被點擊時,我們是否應該進入server.R的隔離部分。之後,完成一些計算,並將文件返回給用戶。但是,我無法正確隔離,即使沒有點擊ActionButton,文件也會被退回。這裏是我的應用程序:ř光澤:隔離會話變量

server.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.") 
)) 

回答

3

你的問題是完全無關的會話變量。實際觸發計算的唯一事件是input$upload。如果上傳的是空的代碼打以下行

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

,一切都按預期工作。如果文件已經上傳,您的程序將達到隔離區塊。即使你把input$start_proc

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

:正在使用isolate未包含任何變量不認爲是這樣下面的代碼的一部分,沒有任何效果可言的依賴,你在評論做出的假設是完全錯誤的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

與分離的東西好主意。但是,點擊按鈕會不斷增加,因此只需檢查它是否等於0是不夠的。 – Cauchy

+0

如果你想支持多個上傳,提取處理邏輯和按鈕處理程序是有意義的。 – zero323