【问题标题】:Shiny initial textAreaInput value and reactive after each button press每次按下按钮后闪亮的初始 textAreaInput 值和反应
【发布时间】:2017-08-01 20:28:24
【问题描述】:

说明

我有一个textAreaInput 框,我想从默认值开始。用户可以点击2actionButtons提交 & 随机评论)。 Submit 更新来自textAreaInput 的评论以供进一步处理(情节等),而Random Comment 将新的随机值发送到textAreaInput(用户可以输入textAreaInput 框也是如此)。我几乎拥有它,但在按下 Submit 按钮之前,无法让应用程序更新textAreaInputvalue

问题

我希望在按下 Random Comment 时更新它,但仍允许用户擦除文本框并键入自己的文本。我怎样才能让应用程序做到这一点?

MWE

library(shiny)
library(shinyjs)
library(stringi)

shinyApp(
    ui = fluidPage(
      column(2,
        uiOutput("randcomment"),
        br(),
        div(
            actionButton("randtext", "Random Comment", icon = icon("quote-right")),
            div(actionButton("submit", "Submit", icon = icon("refresh")), style="float:right")
        )

      ),
      column(4, div(verbatimTextOutput("commenttext"), style = 'margin-top: 2cm;'))
    ),
    server = function(input, output) {

        output$randcomment <- renderUI({
            commentUi()
        })

        comment_value <- reactiveValues(default = 0)

        observeEvent(input$submit,{
            comment_value$default <- input$randtext
        })

        renderText(input$randtext)

        commentUi <- reactive({

            if (comment_value$default == 0) {
                com <- stri_rand_lipsum(1)
            } else {
                com <- stri_rand_lipsum(1)
            }

            textAreaInput("comment", label = h3("Enter Course Comment"), 
                value = com, height = '300px', width = '300px')
        })

        output$commenttext <- renderText({ input$comment })


    }
  )

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    我会以不同的方式处理这个问题。我会使用reactiveValues 填充这两个字段,然后使用两个observeEvents 来控制reactiveValues 的内容。

    在这种情况下,我认为您根本不需要reactive。当您想要立即处理时,reactive 很好。如果您想控制处理值的时间,请使用reactiveValues

    library(shiny)
    library(shinyjs)
    library(stringi)
    
    shinyApp( 
      ui = fluidPage(
        column(2,
               uiOutput("randcomment"),
               br(),
               div(
                 actionButton("randtext", "Random Comment", icon = icon("quote-right")),
                 div(actionButton("submit", "Submit", icon = icon("refresh")), style="float:right")
               )
    
        ),
        column(4, div(verbatimTextOutput("commenttext"), style = 'margin-top: 2cm;'))
      ),
      server = function(input, output) {
    
        # Reactive lists -------------------------------------------------------
        # setting the initial value of each to the same value.
        initial_string <- stri_rand_lipsum(1)
        comment_value <- reactiveValues(comment = initial_string,
                                        submit = initial_string)
    
        # Event observers ----------------------------------------------------
        observeEvent(input$randtext,
          {
            comment_value$comment <- stri_rand_lipsum(1)
          }
        )
    
        # This prevents the comment_value$submit from changing until the 
        # Submit button is clicked. It changes to the value of the input
        # box, which is updated to a random value when the Random Comment
        # button is clicked.
        observeEvent(input$submit,
          {
            comment_value$submit <- input$comment
          }
        )
    
        # Output Components -------------------------------------------------
        # Generate the textAreaInput
        output$randcomment <- renderUI({
          textAreaInput("comment", 
                        label = h3("Enter Course Comment"), 
                        value = comment_value$comment, 
                        height = '300px', 
                        width = '300px')
        })
    
        # Generate the submitted text display
        output$commenttext <- 
          renderText({ 
            comment_value$submit 
          })
      }
    )
    

    代码中的一些 cmets

    我在确定您的代码在做什么时有些吃力。部分原因是您的服务器功能组织有点混乱。你的组件是

    • 输出
    • 反应式列表
    • 观察者
    • 输出(但未分配到插槽...多余)
    • 反应对象
    • 输出

    我建议将您的反应式组合在一起,将您的观察者组合在一起,并将您的输出组合在一起。如果你有真正独立的系统,你可以将系统分成不同的代码部分,但让它们遵循类似的模式(我认为这两个框是同一个系统的一部分)

    您的commentUi 反应式有一个奇怪的if-else 结构。它总是将com 设置为随机字符串。更重要的是,if-else 构造并不是真正必要的,因为您的代码中没有任何地方更新过comment_value$default——它始终为 0。看起来您可能一直在尝试将其作为操作按钮的基础某个点,然后(正确地)得出结论,这不是一个很好的选择。

    另外,我建议不要在反应式对象中构建 UI 组件。如果您的反应器返回值,然后在 render 函数系列中构建任何 UI 组件,您会发现您的反应器更加灵活和有用。

    【讨论】:

    • 这是我收到的最好的答案之一。感谢您花时间写它。建设性的反馈真的很有帮助。感谢您抽出宝贵时间发帖。
    • 我很高兴你能建设性地接受它。看了你的名声,差点没把批评包括进去。
    猜你喜欢
    • 2017-11-15
    • 2018-08-01
    • 2019-08-02
    • 2018-02-08
    • 2021-05-01
    • 2019-02-02
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多