R Shiny-在Shiny模块中以编程方式触发初始insertUI事件

时间:2019-07-29 08:33:06

标签: r shiny reactive-programming shinymodules

下面的应用程序包含一个selectInputinput$month)和一个按钮Show Modal,单击该按钮会启动一个模式窗口。模态包含一个按钮Add UI,该按钮插入一些文本Element x,其中x是每次单击Add UI时计数器值都会增加1。 / p>

启动并打开模式窗口的应用截图:

enter image description here

该应用程序已模块化,因此与模态相关联的UI由功能modUI呈现,并且相应的服务器逻辑在功能modServer中定义。每次modUI进行更改以覆盖先前插入的文本元素时,input$month都会重新呈现。

我需要以编程方式插入第一行文本,以便在应用加载 OR 时,用户更改input$month时,Element 1已呈现在模态

enter image description here

为此,我尝试让insertUI观察器在input$add_ui大于或等于0(即observeEvent(if(req(input$add_ui) >= 0) TRUE else return(), { #insertUI expr }))时触发。但是,这不起作用,我也不明白为什么。 由于对观察者进行了热切的评估,因此input$add_ui完成初始化后,该观察者是否应该解雇?

每次input$month更改时,计数器也必须重置为0,以便插入的文本元素从Element 1开始。为此,我在modServer中加入了以下观察者:

observe({
    req(input$add_ui == 0) #checking that modUI has finished rerendering
    print(paste('month changed to:', month, 'resetting counter')); 
    counter(0)
  })

req(input$add_ui == 0)检查modUI是否已完成重新渲染,并且仅在通过检查后才重置计数器。 但是我觉得这样会使modServer的设备越来越少,并且想知道是否有更小的回旋路吗?

最近,我对模块还比较陌生,想知道是否有人可以解释为什么通过counter()调用modServerobserve(callModule(modServer, 'hi', month = input$month))不会自动重置?如果模块具有自己的环境,为什么它的值仍然存在?

我将不胜感激,因为我一直坚持这一时间。

用于复制以上代码的代码:

library(shiny)
library(shinyBS)

#MODULE UI ----
modUI <- function(id) {

  ns <- NS(id)

  tagList(
    actionButton(ns("show_modal"), "Show modal"),
    bsModal(
      id = ns('modal'),
      trigger = ns('show_modal'),

      actionButton(ns("add_ui"), "Add UI"),
      tags$div(id = ns("placeholder1"))
    )
  )
}

#MODULE SERVER ----
modServer <- function(input, output, session, month) {

  ns <- session$ns

  counter <- reactiveVal(0)

  # Observer to insert UI element
  observeEvent(if(req(input$add_ui) >= 0) TRUE else return(), {

    counter(counter() + 1)

    insertUI(
      selector = paste0("#", ns("placeholder1")),
      ui = tags$div(paste('Element', counter()))
    )
  })

  # Reset counter() if month is changed
  observe({
    req(input$add_ui == 0)
    print(paste('month changed to:', month, 'resetting counter')); 
    counter(0)
  })

  # Print
  observe({ print(paste('input$add_ui:', input$add_ui, 'counter:', counter())) })

}

#MAIN UI ----
ui <- fluidPage(
  tagList(
    selectInput('month', 'Month', month.abb),
    uiOutput('modal_ui')
  )
)

#MAIN SERVER ----
server <- function(input, output, session) {

  #Call modUI if input$month is changed
  observe(callModule(modServer, 'hi', month = input$month))

  #Rerender modUI if input$month is changed
  output$modal_ui <- renderUI({
    input$month
    modUI('hi')
  })

  observe(print(input$month))
}

shinyApp(ui = ui, server = server)

0 个答案:

没有答案