4

我想构建一个 R Shiny 应用程序,它能够将信息从一个正在运行的实例传递到其他可能的运行实例。到目前为止,我没有发现任何可以帮助我解决这个问题的方法,我希望能做对,而不是求助于全局变量和/或写入文件等(我在下面的示例中使用了全局变量,我知道这是一个不好的做法;而且我怀疑写入文件也不是一个好习惯)。

例如,假设我的 App.R 在服务器上运行,并且TimJackJohn将其打开。当JackJohn同时使用该应用程序并按下下例所示的按钮时,如何让Tim看到下面的内容?

应用程序R:

library(shiny)

# Somehow interactively visible variable? (I know global variables are bad, I wouldn't want to use such)
txt <<- ""

shinyApp(
    ui = fluidPage(
        textInput("name", "User name", value="USERNAME"),
        actionButton("button", "Button"),
        htmlOutput("text")
    ),
    server = function(input, output, session){
        a <- eventReactive(input$button, {
            txt <<- paste(txt, "Button pressed by", input$name, "at", Sys.time(), "<br>")
            txt

        })
        output$text <- reactive({
            HTML(a())
        })
    }
)

在浏览器中运行应用程序实例的各个用户按下多个按钮后所需的输出示例(都选择了唯一的 input$name,但显然唯一的会话 id 会更好):

示例用户案例

任何见解将不胜感激,谢谢!

4

1 回答 1

5

我已经在一个闪亮的服务器实例上测试了你的代码,它按预期工作:即我得到了一个类似于你要求的打印输出。

我有点困惑:你到底在找什么?

无论如何,作为一般性评论,我不同意 using<<-是错误的或global variables(通常或在闪亮的应用程序中)是bad

它们有自己的位置,一个典型的用例是跨会话/用户传递状态。

另一种方法是使用shiny reactiveValues如下:

 values <- reactiveValues()
 values$lognames <- ''
 ...
 ui <- (...)

 server <- function(input, output, session){

 a <- eventReactive(input$button, {
 values$lognames <- paste(values$lognames, "Button pressed by", input$name, "at", Sys.time(), "<br>")
 values$lognames
 })
...
 }

但作为一个普遍的警告,这种类型的设计虽然可能,但最终可能会给应用程序带来状态性,迅速增加其复杂性,并与reactive范式的简单性背道而驰。

我强烈的建议是在这条道路上的每一步之前都要仔细考虑。我有过实现闪亮应用程序的经验,这些应用程序的复杂性随着这些states. 我必须跟踪所有导致应用程序脆弱、难以调试的状态变化。

于 2016-12-26T05:28:57.357 回答