首页 > 解决方案 > 闪亮的代码设计——我应该把复杂的逻辑放在哪里?

问题描述

致所有 R Shiny 专家:您会评价以下三个服务器功能中的哪个第一、第二和第三 - 为什么?

今天我就这三种解决方案中的哪一种最接近“最佳实践”闪亮应用程序设计进行了深入讨论。(虽然它们三者的工作方式相同。)

例如,版本 C 对我来说似乎很奇怪,因为有条件地覆盖渲染函数是不必要的(因为条件输出渲染是这些函数的用途)。

当然,原始应用程序在处理输入值时包含更多逻辑。我简化了示例以使差异明显。

library(shiny)

ui <- fluidPage(

  shiny::radioButtons(
    inputId = "some_input", 
    label = "Please choose:", 
    choices = c("something", "nothing")
  ),

  shiny::textOutput(
    outputId = "some_output"
  )  

)

# version A: all logic within rendering function
server <- function(input, output, session) {

   output$some_output <- shiny::renderText({

       if(input$some_input == "something"){
         # imagine some complex logic here
         "some value was chosen"
       } else {
         NULL
       }

   })

}

# version B: most logic within input observer, 
# using reactive session userData
server <- function(input, output, session) {

  session$userData$memory <- shiny::reactiveValues(
    "stored_value" = NULL
  )

  output$some_output <- shiny::renderText({
    session$userData$memory$stored_value
  })

  shiny::observeEvent({
    input$some_input
  }, {

    if(input$some_input == "something"){
      # imagine some complex logic here
      session$userData$memory$stored_value <- "some value was chosen"
    } else {
      session$userData$memory$stored_value <- NULL
    }
  })

}

# version C: all logic within observer, 
# setting the rendering function conditionally
server <- function(input, output, session) {

  shiny::observeEvent({
    input$some_input
  }, {

    if(input$some_input == "something"){
      # imagine some complex logic here
      output$some_output <- shiny::renderText({ "some value was chosen" })
    } else {
      output$some_output <- shiny::renderText({ NULL })
    }

  })

}

shinyApp(ui = ui, server = server)

标签: rsessionshinylistenershiny-reactivity

解决方案


我绝不是 Shiny 专家,但由于没有定义“最佳”,我想我会根据我创建的应用程序给出我的意见(没有提供支持的文档)。

从最好到最差的顺序:

  1. 一个
  2. C

推理:

C:虽然output$some_output在多个地方工作,但这样做从来都不是好习惯,只会在代码中造成混乱

B:observeEvent是重复的,因为renderText()它旨在观察反应变量何时发生变化。我知道你有一个更复杂的应用程序,但reactiveValues在这个例子中存储到上面没有任何好处。

答:非常简单的基本代码,可以无缝运行。您也可以争辩说您可以将其if statement取出renderText()并将其包裹在 areactive()中以保持清洁,但它们完成了同样的事情。

我很好奇是否有人会做时间研究或有一些实际文件来支持“最好”到“最差”。


推荐阅读