我正在创建一个Shiny应用程序,该应用程序在数据表中显示图像和文本。该表将需要根据用户输入进行更新。当我在窗口中运行应用程序时,表将按预期更新。但是,当我在浏览器中运行它时,文本会更新,但图像不会更新。如何使其在浏览器中工作?
编辑:为清楚起见,下面的示例仅用于重现该问题。真正的应用程序可以显示任意数量的不同图片,直到用户做出选择(从数据库中提取出来)后,这些图片才会保存在本地。我希望避免使用不同的文件名,因为我最终可能会在本地保存成千上万张图片,但是如果这是唯一的解决方案,那么我将不得不定期清理文件夹
可复制的示例(需要2张本地图片)
library(shiny)
library(imager)
library(DT)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("Tables to export"),
sidebarLayout(
sidebarPanel(
actionButton("pic1","Pic1"),
actionButton("pic2","Pic2")
),
# Show tables
mainPanel(
fluidRow(
dataTableOutput('tab1')
)
)
)
)
# Define server logic
server <- function(input, output) {
observeEvent(input$pic1, {
pic <- load.image("www/pic1.png")
save.image(pic,"www/picToShow.png")
tab1 <- datatable(t(data.frame("Pic"='<img src="picToShow.png" width=150 height=100>',x1=1,x2=2,x3=3,row.names="p1")),
escape = F, options = list(dom = 't',pageLength = 20))
output$tab1 <- renderDataTable(tab1)
})
observeEvent(input$pic2, {
pic <- load.image("www/pic2.png")
save.image(pic,"www/picToShow.png")
tab1 <- datatable(t(data.frame("Pic"='<img src="picToShow.png" width=150 height=100>',x1=4,x2=5,x3=6,row.names="p1")),
escape = F, options = list(dom = 't',pageLength = 20))
output$tab1 <- renderDataTable(tab1)
})
}
# Run the application
shinyApp(ui = ui, server = server)
预期行为(窗口中的行为)
浏览器中的行为
答案 0 :(得分:2)
我同意@MrFlick的评论。为什么要加载两个图像并以相同的名称重新保存它们?浏览器会认为它已经知道该图像,并将重新使用已经加载的图像。
为什么不直接包含pic1.png
和pic2.png
?
server <- function(input, output) {
observeEvent(input$pic1, {
tab1 <- datatable(t(data.frame("Pic"='<img src="pic1.png" width=150 height=100>',x1=1,x2=2,x3=3,row.names="p1")),
escape = F, options = list(dom = 't',pageLength = 20))
output$tab1 <- renderDataTable(tab1)
})
observeEvent(input$pic2, {
tab1 <- datatable(t(data.frame("Pic"='<img src="pic2.png" width=150 height=100>',x1=4,x2=5,x3=6,row.names="p1")),
escape = F, options = list(dom = 't',pageLength = 20))
output$tab1 <- renderDataTable(tab1)
})
}
答案 1 :(得分:2)
library(shiny)
library(imager)
library(DT)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("Tables to export"),
sidebarLayout(
sidebarPanel(
actionButton("pic1","Pic1"),
actionButton("pic2","Pic2")
),
# Show tables
mainPanel(
fluidRow(
DT::dataTableOutput('tab1')
)
)
)
)
# Define server logic
server <- function(input, output) {
vals = reactiveValues(pic1 = 0, pic2 = 0)
observeEvent(input$pic1, {
vals$pic1 <- 1
vals$pic2 <- 0
})
observeEvent(input$pic2, {
print(vals$pic1)
print(vals$pic2)
vals$pic1 <- 0
vals$pic2 <- 1
})
dynamicdf <- reactive({
if(vals$pic1 == 1) {
df <- data.frame(
pic = c('<img src="http://flaglane.com/download/american-flag/american-flag-large.png" height="52"></img>'),
x1 = c(1),
x2 = c(2),
x3 = c(3)
)
} else {
df <- data.frame(
pic = c('<img src="img2.jpg" width=150 height=100></img>'),
x1 = c(4),
x2 = c(5),
x3 = c(6)
)
}
print(df)
return(df)
})
output$tab1 <- DT::renderDataTable({
DT::datatable(dynamicdf(), escape = FALSE)
})
}
# Run the application
shinyApp(ui = ui, server = server)
在Shiny Apps中,您不会加载或保存图像。您可以使用存储图片的文件夹路径来显示它们。这可以是互联网上的链接,也可以是机器上的路径。
这样做。我使用reactiveValue
来跟踪按钮的最后点击。如果您要渲染大量图片,这是一个很好的解决方案。 (我从现代JS库ReactJS中采用了这种样式)根据显示图片的状态。 不要使用www
路径,这已经是闪亮的期望值。使其与应用程序中的example2一样。
对我来说,它还只能与App中的escape = FALSE
参数一起使用。如果没有它就无法正常工作。