2017-06-27 38 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