簡體   English   中英

使用不同的輸入小部件類型更新多個閃亮的應用程序輸入

[英]Update multiple shiny apps inputs with different input widget types

我設計了一個帶有兩個操作按鈕SaveClear的 Shiny 應用程序。 當用戶單擊Save ,輸入值將使用 Web 瀏覽器的本地存儲進行存儲。 當用戶點擊Clear ,輸入和本地存儲將被清除。

這些功能涉及使用update...Input更新多個update...Input 在這個例子中,我有三個輸入,它們都具有不同的小部件類型。 具體可以一一寫出來,效果很好。 但是,我想知道是否有更有效的方法來實現這一點,例如使用for looplapply 從這篇文章( https://stackoverflow.com/a/41061114/7669809 )來看,我似乎可以使用reactiveValuesToList來獲取所有輸入。 對我來說真正的挑戰是如何為關聯的輸入小部件類型動態調用不同的update...Input函數?

如果您有任何建議,請告訴我。

### This script creates an example of the shinystore package

# Load packages
library(shiny)
library(shinyStore)

ui <- fluidPage(
  headerPanel("shinyStore Example"),
  sidebarLayout(
    sidebarPanel = sidebarPanel(
      initStore("store", "shinyStore-ex1"),
      textInput(inputId = "Text1", label = "Enter some texts")
    ),
    mainPanel = mainPanel(
      fluidRow(
        numericInput(inputId = "Number1", label = "Enter a number", value = NA),
        sliderInput(inputId = "Slider1", label = "Pick a number", min = 0, max = 100, value = 50),
        actionButton("save", "Save", icon("save")),
        actionButton("clear", "Clear", icon("stop"))
      )
    )
  )
)

server <- function(input, output, session) {
  observe({
    if (input$save <= 0){
      updateTextInput(session, inputId = "Text1", value = isolate(input$store)$Text1)
      updateNumericInput(session, inputId = "Number1", value = isolate(input$store)$Number1)
      updateSliderInput(session, inputId = "Slider1", value = isolate(input$store)$Slider1)
    }
    updateStore(session, name = "Text1", isolate(input$Text1))
    updateStore(session, name = "Number1", isolate(input$Number1))
    updateStore(session, name = "Slider1", isolate(input$Slider1))
  })
  
  observe({
    if (input$clear > 0){
      updateTextInput(session, inputId = "Text1", value = NA)
      updateNumericInput(session, inputId = "Number1", value = NA)
      updateSliderInput(session, inputId = "Slider1", value = 50)
      
      updateStore(session, name = "Text1", value = NA)
      updateStore(session, name = "Number1", value = NA)
      updateStore(session, name = "Slider1", value = 50)
    }
  })
}

shinyApp(ui, server)

不幸的是, shiny沒有通用的updateInput函數。 仍然可以構建一個包裝器,將某個名稱標識為某個輸入類型,但這也需要知道允許或不允許哪個參數。 例如, updateActionButton沒有valuechoices作為參數,因此我們需要大量的 if 語句。

一種可能的解決方法是利用renderUI並直接傳遞存儲的值。 唯一的缺點是,當某些參數為 NULL 時,諸如SliderInput類的某些函數SliderInput引發錯誤,因此在應用程序首次運行時需要使用 if 語句來指定默認值。 或者,可以執行一次模擬應用程序以僅填充第一個值。

代碼:

library(shiny)
library(shinyStore)
library(tidyverse)

ui <- fluidPage(
    initStore("store", "shinyStore-ex1"),
    uiOutput('ui_all'))

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

    output$ui_all <- renderUI({
      tagList(
        headerPanel("shinyStore Example"),
        sidebarLayout(
            sidebarPanel = sidebarPanel(
                textInput(inputId = "Text1", label = "Enter some texts",value = input$store$Text1)
            ),
            mainPanel = mainPanel(
                fluidRow(
                    numericInput(inputId = "Number1", label = "Enter a number", value = input$store$Number1),
                    sliderInput(inputId = "Slider1", label = "Pick a number", min = 0, max = 100, value = if(is.null(input$store$Slider1)){50} else{input$store$Slider1}),
                    actionButton("save", "Save", icon("save")),
                    actionButton("clear", "Clear", icon("stop"))
                )
            )
        ))
    })
    
     
    input_nms <- map(c('Text', 'Number', 'Slider'), ~str_c(.x, 1:1)) %>%
                    reduce(c)
    
    #or if every type of input is repeteated n different times.
    # input_nms <- map2(c('Text', 'Number', 'Slider'), c(n1, n2, n3), ~str_c(.x, 1:.y)) %>%
    #     reduce(c)
    
        
    observeEvent(input$save, {
       input_nms %>% 
            walk(~updateStore(session = session, name = .x, value =  isolate(input[[.x]])))
            session$reload() #to force the UI to render again with the new values
    })
    
    observeEvent(input$clear, {
        input_nms %>% 
            walk2(c(NA, NA, 50), ~updateStore(session = session, name = .x, value = .y))
    })
}

shinyApp(ui, server)

暫無
暫無

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

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