2017-06-27 39 views
0

我遇到了轻微的问题(bug也许?)与Shiny的书签 - 我创建动态UI - 新的文本和数字输入。这些输入是通过单击ActionButton创建的。保存书签网址时 - 数字和文字输入的值都在此URL中。到现在为止还挺好。但是,加载保存的URL后,我只能看到第一个动态创建的用户界面。我必须点击动作按钮来添加下一个数字和文本输入。这些值保存在URL中,一旦添加了这些输入,它们就会被填充正确的保存值。但是,如果你有20个这样的按钮,那么它会有点不方便,你必须点击19次才能将它们全部放到屏幕上。 这是一个简短的可重复使用的例子。R Shiny - 书签动态创建的用户界面

library(shiny) 

ui <- function(request){ 
    shinyUI(fluidPage(
    bookmarkButton(), 
    sidebarLayout(
     actionButton('addElement', 'Add Element', icon("plus"), class="btn-success text-white"), 
    mainPanel(
     id ="content" 
    ) 
    ) 
)) 
} 


shinyServer(function(input, output) { 
    enableBookmarking("url") 
    countvar <<- 0 
    observeEvent(input$addElement, { 
    countvar <<- countvar + 1 
    element <- paste0("var", countvar) 
    insertUI(
     selector = "#content", 
     where = "beforeEnd", 
     ui = tagList(
     wellPanel(
      style = "display:-webkit-inline-box;width:100%", 
      id = element, 
      column(3, 
       textInput(element, "Element name") 
     ), 
      column(3, 
       numericInput(paste0(element, "Value"), "Element Value", NULL) 
     ) 
     ) 
    ) 
    ) 
    }) 

}) 

我发现SO,遗憾的是没有答案类似的问题 - Shiny app bookmarking: dynamic UI input lost

+0

您需要使用'OnRestore中()'函数。看看这篇文章:https://shiny.rstudio.com/articles/advanced-bookmarking.html –

+0

嗨芭芭拉,感谢您的链接。我想我会看到问题出在哪里 - 即使是在addElement的值超过1的URL中,也只会触发一次。然而,我不知道我应该如何将'onRestore()'函数合并到我的代码中。我究竟应该调用什么 - 触发代码的“observeElement”部分?或者干脆在纯HTML中解析?谢谢,我在这一点上有点失落。 – ledogbert

回答

0

这里是改编自您的应用程序小例子。在添加书签之后,在页面上获取动态内容并没有什么神奇的方式(除非您以直接的方式使用renderUI - 即没有任何非输入状态)。因此,对于您的情况,您只需在onRestore()回拨中重复在应用中执行的工作即可。这样做的最好方法是重构你的代码,这样就可以调用一个函数来在普通应用程序和回调函数内添加项目。

library(shiny) 

ui <- function(request) { 
    fluidPage(
    bookmarkButton(), 
    sidebarLayout(
     actionButton("add", "Add Element"), 
     mainPanel(id = "content") 
    ) 
) 
} 

server <- function(input, output, session) { 

    addItem <- function(id, textId, numberId, textVal = "", numberVal = NULL) { 
    insertUI(
     selector = "#content", 
     where = "beforeEnd", 
     ui = tagList(
     wellPanel(style = "display:-webkit-inline-box;width:100%", 
      id = id, 
      column(3, textInput(textId, "Element name", textVal)), 
      column(3, numericInput(numberId, "Element value", numberVal)) 
     ) 
    ) 
    ) 
    } 

    observeEvent(input$add, { 
    id <- paste0("var", input$add) 
    textId <- paste0(id, "text") 
    numberId <- paste0(id, "number") 
    addItem(id, textId, numberId) 
    }, ignoreInit = TRUE) 

    onRestore(function(state) { 
    for (i in seq_len(input$add)) { 
     id <- paste0("var", i) 
     textId <- paste0(id, "text") 
     numberId <- paste0(id, "number") 
     addItem(id, textId, numberId, input[[textId]], input[[numberId]]) 
    } 
    }) 
} 

enableBookmarking("url") 
shinyApp(ui, server) 
+0

我很害怕那会是这样 - 我有很多这种动态生成的内容,所以总体上它会有点混乱。非常感谢您的时间,欣赏输入! – ledogbert

+0

另外我意识到我可以在observeEvent handlerExpr中使用一个函数。因此,我创建了一个函数,我称其为observeEvent和onRestore阶段。到目前为止,它工作得很好。 – ledogbert