簡體   English   中英

R Shiny模塊帶有conditionalPanel和reactives

[英]R Shiny modules with conditionalPanel and reactives

我試圖模塊化一個復雜的Shiny應用程序,我有一個conditionalPanel面板應該只出現給定一個輸入狀態。

在我將所有內容都模塊化之前,輸入和conditionalPanel都在ui.R ,我可以使用以下內容引用輸入:

conditionalPanel("input.select == 'Option one'", p('Option one is selected'))

現在我已經模塊化了,訪問輸入更加復雜。 我認為以下是這樣做的方法,但它並不是很有效。 (這里我把東西組合成一個獨立的腳本):

library(shiny)

## Module code for 'selectorUI' and 'selector'
selectorUI <- function(id) {
  ns <- NS(id)
  selectizeInput(inputId = ns('select'),
                 label = 'Make a choice:',
                 choices = c('Option one', 'Option two'))
}

selector <- function(input, output, session) {
  reactive(input$select)
}

## Main app
ui <- shinyUI(fluidPage(
  selectorUI('id1'),
  conditionalPanel(condition = "output.selected == 'Option one'", p('Option one is selected.'))
))

server <- shinyServer(function(input, output, session) {
  output$selected <- callModule(selector, 'id1')
})

shinyApp(ui = ui, server = server)

我認為這應該有效,但它不起作用 - 它只有在我對主ui部分中output$selected進行另一個引用時才有效:

ui <- shinyUI(fluidPage(
  selectorUI('id1'),
  textOutput('selected'),   ## Adding just this one line makes the next line work
  conditionalPanel(condition = "output.selected == 'Option one'", p('Option one is selected.'))
))

不幸的是,當然這會產生渲染textOutput('selected')結果的不良影響。 我只能猜測它的工作原因是因為它以某種方式觸發反應,而JavaScript引用本身並沒有。

知道如何讓這個conditionalPanel正常工作嗎?

謝謝..

編輯:原來並不是一個錯誤: https//github.com/rstudio/shiny/issues/1318 請看下面我自己的答案。

但是請注意,我實際上喜歡在接受的答案中給出的renderUI解決方案比我原來的conditionalPanel方法更好。

調用模塊后, selectizeInput的ID為id1-select 在javaScript中,有兩種訪問對象屬性的方法:

objectName.propertyobjectName['property']

由於存在-ID ,我們必須通過字符串引用它,所以第二個方法是路要走。

conditionalPanel中的conditionalPanel變為:

input['id1-select'] == 'Option one'

完整示例:

library(shiny)

## Module code for 'selectorUI' and 'selector'
selectorUI <- function(id) {
  ns <- NS(id)
  selectizeInput(inputId = ns('select'),
                 label = 'Make a choice:',
                 choices = c('Option one', 'Option two'))
}

## Main app
ui <- shinyUI(fluidPage(
  selectorUI('id1'),
  conditionalPanel(condition = "input['id1-select'] == 'Option one'",
                   p('Option one is selected.'))
))

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

})

shinyApp(ui = ui, server = server)

編輯:

這確實有效,但是它是否違反了模塊化的概念? 你必須知道模塊的代碼在內部調用輸入'select'以構造'id1-select'。

你是對的。

根據這篇文章 ,你使用的技巧,即將模塊調用分配給輸出$ selected,然后通過output.selected在客戶端訪問它的值應該可以工作,但事實並非如此。 我不知道為什么......這可能是個錯誤。 (我有來自github的最新閃亮版本)

我唯一能想到的是使用renderUI而不是conditionalPanel ,如下例所示:

library(shiny)
## Module code for 'selectorUI' and 'selector'
selectorUI <- function(id) {
  ns <- NS(id)
  selectizeInput(inputId = ns('select'),
                 label = 'Make a choice:',
                 choices = c('Option one', 'Option two'))
}

selector <- function(input, output, session) {
  reactive(input$select)
}

## Main app
ui <- shinyUI(fluidPage(
  selectorUI('id1'),
  uiOutput("dynamic1")
))

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


  output$dynamic1 <- renderUI({
    condition1 <- callModule(selector, 'id1') # or just callModule(selector, 'id1')()
    if (condition1() == 'Option one') return(p('Option one is selected.'))
  })

})

shinyApp(ui = ui, server = server)

原來它實際上不是一個bug,只是有點棘手。 據Joe Cheng說

右 - 默認情況下,如果它們不可見,我們不會計算/渲染輸出值。 如果我們不計算它們,你就不能在條件下使用它們。

您可以通過設置每次計算輸出來更改此行為,您可以在服務器中使用它.R(將outputId替換為相應的值):

outputOptions(output, "outputId", suspendWhenHidden = FALSE)

因此,為了解決我的原始示例的問題,我們只需要將一行添加到服務器函數:

server <- shinyServer(function(input, output, session) {
  output$selected <- callModule(selector, 'id1')
  outputOptions(output, 'selected', suspendWhenHidden = FALSE) # Adding this line
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM