在 observeEvent 中更新输入并更改 ui
Update input and change ui within observeEvent
我正在尝试让以下内容在 Shiny App 中运行:
- 有两个页面,每个页面由不同的 UI
定义
- 显示的第一个页面有一个带有一些默认文本的文本输入(即
textInput("text", "Text Input", "word")
)
- 当用户单击按钮时:(1)
input$text
的值通过 updateTextInput 更新,(2) 页面切换。
第三部分不适合我。我已经定义了一个 actionButton,当它被点击时,我有两个被触发的 observeEvents:第一个带有 updateTextInput,第二个更新页面。问题是 input$text
没有被更新——似乎 updateTextInput 被忽略了。
当我注释掉切换 ui 的 observeEvent 时,updateTextInput 按预期工作。
知道如何让按钮既更新文本又切换 UI 吗?这是我正在制作的更大应用程序的一部分,但下面的示例重现了这个问题。
# UIs --------------------------------------------------------------------------
ui = (htmlOutput("page"))
ui_page1 = fluidPage(
h1("Page 1"),
actionButton("to_page2", "Go to Page 2"),
textInput("text", "Text Input", "word")
)
ui_page2 <- fluidPage(
h1("Page 2"),
actionButton("to_page1", "Go to Page 1"),
br(),
h4("Displaying input$text - I want this show `new word`"),
textOutput("input_text")
)
# Server -----------------------------------------------------------------------
server = function(input, output, session) {
#### By default, start with page 1
output$page <- renderUI({
div(ui_page1)
})
#### To page 2
observeEvent(input$to_page2, {
updateTextInput(session, "text", value = "new word")
}, priority = 3)
# *** Comment this observeEvent out, and the updateTextInput works as expected
observeEvent(input$to_page2, {
output$page <- renderUI({
div(ui_page2)
})
}, priority = 2)
# To display the input$text value
observeEvent(input$to_page2, {
output$input_text <- renderText(input$text)
}, priority = 1)
#### To page 1
observeEvent(input$to_page1, {
output$page <- renderUI({
div(ui_page1)
})
})
}
# shinyApp ---------------------------------------------------------------------
shinyApp(ui, server)
我不想给出类似“这行得通,但我不知道为什么”这样的答案,但是...
这行得通,我不知道为什么。
我更改了您的服务器功能,以便在 reactiveValues
对象中加注第 2 页上显示的单词。没有其他变化。
server = function(input, output, session) {
v <- reactiveValues(
word="word"
)
#### By default, start with page 1
output$page <- renderUI({
div(ui_page1)
})
observeEvent(input$input_word, {
v$word <- input$input_word
})
#### To page 2
observeEvent(input$to_page2, {
v$word <- "new word"
updateTextInput(session, "text", value = v$word)
}, priority = 100)
# *** Comment this observeEvent out, and the updateTextInput works as expected
observeEvent(input$to_page2, {
output$page <- renderUI({
div(ui_page2)
})
}, priority = 200)
# To display the input$text value
observeEvent(input$to_page2, {
output$input_text <- renderText(v$word)
}, priority = 200)
#### To page 1
observeEvent(input$to_page1, {
output$page <- renderUI({
div(ui_page1)
})
})
}
但是在将其粘贴到此处时,我注意到您已经在观察者中定义了 output
对象。这绝不是一个好主意。我会看看这是不是根本原因...
更新
此服务器功能是否为您提供了您想要的行为?如果是这样,您的问题是因为您在 observe
rs...
中定义了 output
对象
server = function(input, output, session) {
renderPageUI <- function(id) {
if (id == 1) ui_page1
else ui_page2
}
#### By default, start with page 1
output$page <- renderUI({
renderPageUI(1)
})
#### To page 2
observeEvent(input$to_page2, {
updateTextInput(session, "text", value = "new word")
renderPageUI(2)
})
#### To page 1
observeEvent(input$to_page1, {
renderPageUI(1)
})
}
顺便说一句,每当我编写这种动态 UI 时,我总是最终将每个动态组件定义为一个模块,即使我知道组件只会有一个实例。它使跟踪 input
和 output
id 属于哪个页面变得容易得多 - 因为它们对其他所有组件都是不可见的,除非我选择使它们可见。
我正在尝试让以下内容在 Shiny App 中运行:
- 有两个页面,每个页面由不同的 UI 定义
- 显示的第一个页面有一个带有一些默认文本的文本输入(即
textInput("text", "Text Input", "word")
) - 当用户单击按钮时:(1)
input$text
的值通过 updateTextInput 更新,(2) 页面切换。
第三部分不适合我。我已经定义了一个 actionButton,当它被点击时,我有两个被触发的 observeEvents:第一个带有 updateTextInput,第二个更新页面。问题是 input$text
没有被更新——似乎 updateTextInput 被忽略了。
当我注释掉切换 ui 的 observeEvent 时,updateTextInput 按预期工作。
知道如何让按钮既更新文本又切换 UI 吗?这是我正在制作的更大应用程序的一部分,但下面的示例重现了这个问题。
# UIs --------------------------------------------------------------------------
ui = (htmlOutput("page"))
ui_page1 = fluidPage(
h1("Page 1"),
actionButton("to_page2", "Go to Page 2"),
textInput("text", "Text Input", "word")
)
ui_page2 <- fluidPage(
h1("Page 2"),
actionButton("to_page1", "Go to Page 1"),
br(),
h4("Displaying input$text - I want this show `new word`"),
textOutput("input_text")
)
# Server -----------------------------------------------------------------------
server = function(input, output, session) {
#### By default, start with page 1
output$page <- renderUI({
div(ui_page1)
})
#### To page 2
observeEvent(input$to_page2, {
updateTextInput(session, "text", value = "new word")
}, priority = 3)
# *** Comment this observeEvent out, and the updateTextInput works as expected
observeEvent(input$to_page2, {
output$page <- renderUI({
div(ui_page2)
})
}, priority = 2)
# To display the input$text value
observeEvent(input$to_page2, {
output$input_text <- renderText(input$text)
}, priority = 1)
#### To page 1
observeEvent(input$to_page1, {
output$page <- renderUI({
div(ui_page1)
})
})
}
# shinyApp ---------------------------------------------------------------------
shinyApp(ui, server)
我不想给出类似“这行得通,但我不知道为什么”这样的答案,但是...
这行得通,我不知道为什么。
我更改了您的服务器功能,以便在 reactiveValues
对象中加注第 2 页上显示的单词。没有其他变化。
server = function(input, output, session) {
v <- reactiveValues(
word="word"
)
#### By default, start with page 1
output$page <- renderUI({
div(ui_page1)
})
observeEvent(input$input_word, {
v$word <- input$input_word
})
#### To page 2
observeEvent(input$to_page2, {
v$word <- "new word"
updateTextInput(session, "text", value = v$word)
}, priority = 100)
# *** Comment this observeEvent out, and the updateTextInput works as expected
observeEvent(input$to_page2, {
output$page <- renderUI({
div(ui_page2)
})
}, priority = 200)
# To display the input$text value
observeEvent(input$to_page2, {
output$input_text <- renderText(v$word)
}, priority = 200)
#### To page 1
observeEvent(input$to_page1, {
output$page <- renderUI({
div(ui_page1)
})
})
}
但是在将其粘贴到此处时,我注意到您已经在观察者中定义了 output
对象。这绝不是一个好主意。我会看看这是不是根本原因...
更新
此服务器功能是否为您提供了您想要的行为?如果是这样,您的问题是因为您在 observe
rs...
output
对象
server = function(input, output, session) {
renderPageUI <- function(id) {
if (id == 1) ui_page1
else ui_page2
}
#### By default, start with page 1
output$page <- renderUI({
renderPageUI(1)
})
#### To page 2
observeEvent(input$to_page2, {
updateTextInput(session, "text", value = "new word")
renderPageUI(2)
})
#### To page 1
observeEvent(input$to_page1, {
renderPageUI(1)
})
}
顺便说一句,每当我编写这种动态 UI 时,我总是最终将每个动态组件定义为一个模块,即使我知道组件只会有一个实例。它使跟踪 input
和 output
id 属于哪个页面变得容易得多 - 因为它们对其他所有组件都是不可见的,除非我选择使它们可见。