[英]How to force evaluation in shiny render when generating dynamic number of elements?
我在 shiny 中生成了一個動態數量的valueBox
,這個數字可以根據用戶輸入而改變。 我設法用一個renderUI
來處理這個問題,我在其中放置了所需數量的valueBoxOutput
,並且我有一個observe
器,它將使用renderValueBox
為它們提供內容。
我的問題是:由於某種原因, renderValueBox
中的代碼實際上是在observe
完成后執行的,所以因為renderValueBox
處於循環中(具有動態數量)但是代碼是在之后對所有輸出執行的循環,我所有的輸出都會得到循環的最后一個值。
這是一個最小的代表:
library(shiny)
library(shinydashboard)
library(shinyWidgets)
# Function
compute <- function(id)
{
print(paste("Compute ", id))
return(id)
}
# UI
ui = shinyUI(fluidPage(
titlePanel("Compare"),
useShinydashboard(),
sidebarLayout(
sidebarPanel(
numericInput("numitems", label = "Number of items", min = 1, max = 10, value = 2)
),
mainPanel(
uiOutput("boxes")
)
)
))
# Server
server = shinyServer(function(input, output, session) {
data <- reactiveValues(
ids = list()
)
output$boxes <- renderUI({
print("boxes")
box_list <- list()
id_list <- list()
for(id in 1:(input$numitems)) {
id_box <- paste0("box_", id)
print(paste("boxes - ", id_box))
id_list <- append(id_list, id_box)
box_list <- append(
box_list,
tagList(
shinydashboard::valueBoxOutput(id_box)
)
)
data$ids <- id_list
}
print("boxes end")
fluidRow(box_list)
})
observe({
print("observe")
for(id_box in data$ids) {
print(paste("observe - ", id_box))
output[[id_box]] <- shinydashboard::renderValueBox(valueBox(id_box, compute(id_box), icon = icon("circle-info"), color = "teal"))
}
print("end observe")
})
})
# Run
shinyApp(ui = ui , server = server)
這是結果:
和控制台輸出:
如您所見,計算(以及一般的渲染)是在觀察函數結束后完成的,並且兩個輸出都將使用設置的最后一個 id_box(因此最后一個循環,box_2),而不是正確使用 box_1 和 box_2 .
我嘗試使用force
,在渲染之外計算 valueBox ,使用反應列表,沒有任何效果,因為無論我做什么,渲染都是在觀察之后評估的,所以無論如何只會使用最后一個循環值。
有誰知道在循環中強制執行的方法嗎? 或者看到另一種實現相同結果的方法?
為什么總是在一個問題上花了半天時間,找了幾十個帖子和論壇,一無所獲,最后決定問一個問題……幾分鍾后我終於找到了答案。
無論如何,糾正此問題的一種方法(在此處找到)是將渲染封裝在local
函數中,如下所示:
observe({
print("observe")
for(id_box in data$ids) {
print(paste("observe - ", id_box))
local({
tmp <- id_box
output[[tmp]] <- shinydashboard::renderValueBox(valueBox(tmp, compute(tmp), icon = icon("circle-info"), color = "teal"))
})
}
print("end observe")
})
現在compute
仍然在observe
結束后被調用,但是 tmp 變量有正確的值:
結果是我想要的:
作為記錄,我已經嘗試使用local
函數,但如果您不將 id_box 復制到另一個變量中,只是為了local
集團,它將無法工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.