如何在 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 中显示

R shiny教程-2:布局用户界面

在 R Shiny 中,当链中的对象被隐藏时,如何维护反应链?

R/Shiny 图不显示在浏览器中

在R Shiny中如何分离滑块输入值并使用它们进行过滤

如何从 Shiny 中的下拉框中根据变量选择动态创建直方图