下面的应用程序包含一个selectInput
(input$month
)和一个按钮Show Modal
,单击该按钮会启动一个模式窗口。模态包含一个按钮Add UI
,该按钮插入一些文本Element x
,其中x
是每次单击Add UI
时计数器值都会增加1。 / p>
启动并打开模式窗口的应用截图:
该应用程序已模块化,因此与模态相关联的UI由功能modUI
呈现,并且相应的服务器逻辑在功能modServer
中定义。每次modUI
进行更改以覆盖先前插入的文本元素时,input$month
都会重新呈现。
我需要以编程方式插入第一行文本,以便在应用加载 OR 时,用户更改input$month
时,Element 1
已呈现在模态:
为此,我尝试让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()
调用modServer
时observe(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)