如何在 Shiny 中引用 ui.R 中的反应元素
Posted
技术标签:
【中文标题】如何在 Shiny 中引用 ui.R 中的反应元素【英文标题】:How to refer to reactive element in ui.R in Shiny 【发布时间】:2019-04-16 09:58:58 【问题描述】:我正在使用 ShinyDND 包制作具有拖放功能的应用程序。我想从输入中传递一个列表作为 dragSetUI 的参数,该函数需要在 ui.R 中运行。我尝试了renderUI和uiOutput,它几乎可以工作,但是拖动的元素无法在放置区域中放置。正如您在下面的示例中看到的那样,非反应性选择就像魅力一样。我尝试创建一个反应性对象以及文本输出,但我找不到有关如何在 ui.R 中引用这些对象的文档。通常人们会在输出中将 output$x 称为“x”,但在这里,如果我在引号之间添加任何内容,它会读取为字符串。我真的被这个困住了。
library(shiny)
library(shinyDND)
nonreactive_choices<-as.list(c("a","b","c"))
ui <- shinyUI(
mainPanel(
textInput("choices","Put here a,b,c:"),
dragSetUI("drag", textval = "reactive_choices"),
dragSetUI("drag", textval = "choice_rv"),
textOutput("reactive_choices"),
dragSetUI("drag", textval = nonreactive_choices),
dropUI("drop")
)
)
server = shinyServer(function(input, output,session)
output$reactive_choices<-reactive(
strsplit(input$choices,",")
)
observe(
chlist<-strsplit(input$choices,",")
choice_rv<-reactiveVal(chlist)
)
)
# Run the application
shinyApp(ui = ui, server = server)
【问题讨论】:
我认为您需要一个包含会话信息的更新功能,以便将反应选择推送到 ui。这对于许多闪亮的小部件来说很常见,但似乎不是为闪亮DND 包创建的。 我曾经使用 library(shinyjqui) 中的 orderInput() 实现了类似的方法。你可能想看看它。 【参考方案1】:让我们看看为什么renderUI
方法不适用于shinyDND
。使用shinyDND
的应用程序链接到dragndrop.js
文件,该文件位于shinyDND
文件夹中。在这个文件中可以看到:
$(document).ready(function()
......
$(".dragelement").on("dragstart",function(e)
e.originalEvent.dataTransfer.setData("Text",e.target.id);
);
......
);
这定义了在开始拖动时对具有类dragelement
的元素执行的操作,并且在文档准备好时定义。 dragSetUI
创建这样的元素。
当您在renderUI
中使用dragSetUI
时,这会创建dragelement
类的新元素。但是$(document).ready
中对这些元素定义的动作对这些新元素无效,因为这个动作是在文档准备好之后定义的,然后在renderUI
的效果之前定义。
解决方案包括在renderUI
内定义事件dragstart
的操作。这有效:
library(shiny)
library(shinyDND)
nonreactive_choices<-as.list(c("a","b","c"))
ui <- shinyUI(
mainPanel(
textInput("choices","Put here d,e,f:"),
dragSetUI("drag", textval = nonreactive_choices),
uiOutput("dragset"),
dropUI("drop")
)
)
server = shinyServer(function(input, output,session)
reactive_choices <- reactive(
strsplit(input$choices,",")[[1]]
)
output$dragset <- renderUI(
tagList(
dragSetUI("drag2", textval = as.list(reactive_choices())),
tags$script('$(".dragelement").on("dragstart",function(e)
e.originalEvent.dataTransfer.setData("Text",e.target.id);
);'
)
)
)
)
# Run the application
shinyApp(ui = ui, server = server)
【讨论】:
【参考方案2】:@ismirsehregal 的评论帮助我找到了解决方案:shinyjqui 可以用于我的目的,它似乎可以在 renderUI 内部工作。这是完全符合我需要的编辑代码。
library(shiny)
library(shinyjqui)
ui <- fluidPage(
textInput("choices","Put here a,b,c:"),
uiOutput("reactiveselect"),
orderInput(inputId = 'drop', label = 'Reactive drop', items = NULL,placeholder = "drop here..."),
verbatimTextOutput("droppedorder")
)
server <- function(input, output)
output$reactiveselect <- renderUI(
req(input$choices)
reactiveitems<- unlist(strsplit(input$choices,","))
orderInput("groupstochoose", "groups to choose from:", connect='drop',items=reactiveitems)
)
output$droppedorder<-
renderPrint(input$drop_order)
shinyApp(ui, server)
【讨论】:
以上是关于如何在 Shiny 中引用 ui.R 中的反应元素的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ui.R 中读取 TextInput,在 global.R 中使用此值处理查询并使用 Shiny 在 server.R 中显示