首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在subModules中不起作用的闪亮反应性

在subModules中不起作用的闪亮反应性
EN

Stack Overflow用户
提问于 2018-02-02 22:58:07
回答 1查看 908关注 0票数 3

由于我的shiny应用程序变得相当大,我最近将一些代码放入模块中(也是为了在不同的地方多次重用代码)。在某种程度上,代码的部分不再像预期的那样工作了。

在这个例子中,我有一个模块,它根据输入元素过滤数据并返回一个反应性data.frame。在mainPanel中,我有一个模块,它从过滤的数据创建一个dataTable。但是反应性不起作用,当我更改selectInput时,dataTable不会更新。

代码语言:javascript
复制
library(shiny)
library(DT)

filtersUI <- function(id) {
  ns <- NS(id)
  selectizeInput(
    ns("Species"), label = "Species",
    choices = levels(iris$Species),
    selected = "virginica"
  )
}

filters <- function(input, output, session, .data) {
  inputs <- reactive({
    list("Species" = input[["Species"]])
  })
  reactive({
    .data[.data$Species %in% inputs()[["Species"]], ]
  })
}

dataTableUI <- function(id) {
  ns <- NS(id)
  DT::dataTableOutput(ns("data.table"))
}

dataTable <- function(input, output, session, .data) {
  output$data.table <- DT::renderDataTable({
    DT::datatable(.data)
  })
}

appUI <- function(id) {
  ns <- NS(id)
  sidebarLayout(
    sidebarPanel(
      filtersUI(ns("filter"))
    ),
    mainPanel(
      dataTableUI(ns("data.table"))
    )
  )
}

app <- function(input, output, session, .data) {
  data.subset <- callModule(filters, "filter", .data = .data)
  callModule(dataTable, "data.table", .data = data.subset())
}

ui <-   fluidPage(
  appUI("app")
)

server <- function(input, output, session) {
  callModule(app, "app", .data = iris)
}

shinyApp(ui, server)

但是,当将代码从subModules复制到app模块时,代码工作正常:

代码语言:javascript
复制
library(shiny)
library(DT)
appUI <- function(id) {
  ns <- NS(id)
  sidebarLayout(
    sidebarPanel(
      selectizeInput(
        ns("Species"), label = "Species",
        choices = levels(iris$Species),
        selected = "virginica"
      )
    ),
    mainPanel(
      DT::dataTableOutput(ns("data.table"))
    )
  )
}

app <- function(input, output, session, .data) {
  inputs <- reactive({
    list("Species" = input[["Species"]])
  })
  data.subset <- reactive({
    .data[.data$Species %in% inputs()[["Species"]], ]
  })
  output$data.table <- DT::renderDataTable({
    DT::datatable(data.subset())
  })
}

ui <-   fluidPage(
  appUI("app")
)

server <- function(input, output, session) {
  callModule(app, "app", .data = iris)
}

shinyApp(ui, server)

在这个简单的例子中,我知道模块化结构看起来有点过分,但是在我的实际应用中,我在模块中有很多代码,为了使这个示例最小化,我删除了这些代码。因此,使用与第一个代码片段相同的模块化结构的解决方案将是很好的。知道为什么会失败吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-03 00:06:37

您做了一个非常好的工作,创建了一个带有子模块的可重用示例。然而,这个问题实际上与子模块无关。您只需要以不同的方式传递反应性对象data.subset。而不是

代码语言:javascript
复制
callModule(dataTable, "data.table", .data = data.subset())

你应该使用

代码语言:javascript
复制
callModule(dataTable, "data.table", .data = data.subset)

传递反应性本身,而不是其当前值。然后,可以像这样在DT::renderDataTable中“解析”该值

代码语言:javascript
复制
output$data.table <- DT::renderDataTable({
    DT::datatable({.data()})                                   
})

按照您对其编码的方式,“构造时”(即未经过滤的数据集)的数据将发送到模块,并且无法在此过程中观察到。

需要明确的是:注释行(## remove parantheses here## add parantheses here)是我从原始代码中更改的惟一行。

代码语言:javascript
复制
library(shiny)
library(DT)

filtersUI <- function(id) {
  ns <- NS(id)
  selectizeInput(
    ns("Species"), label = "Species",
    choices = levels(iris$Species),
    selected = "virginica"
  )
}

filters <- function(input, output, session, .data) {
  inputs <- reactive({
    list("Species" = input[["Species"]])
  })
  reactive({
    .data[.data$Species %in% inputs()[["Species"]], ]
  })
}

dataTableUI <- function(id) {
  ns <- NS(id)
  DT::dataTableOutput(ns("data.table"))
}

dataTable <- function(input, output, session, .data) {
  output$data.table <- DT::renderDataTable({
    DT::datatable({.data()})                                  ## add parantheses here
  })
}

appUI <- function(id) {
  ns <- NS(id)
  sidebarLayout(
    sidebarPanel(
      filtersUI(ns("filter"))
    ),
    mainPanel(
      dataTableUI(ns("data.table"))
    )
  )
}

app <- function(input, output, session, .data) {
  data.subset <- callModule(filters, "filter", .data = .data)
  callModule(dataTable, "data.table", .data = data.subset)    ## remove parantheses here
}

ui <-   fluidPage(
  appUI("app")
)

server <- function(input, output, session) {
  callModule(app, "app", .data = iris)
}

shinyApp(ui, server)

为了总结一下,这里引用了一段从Joe到一个类似问题的话

嗨,马克,linkedScatter本身中的代码是正确的;但是当调用callModule时,您希望通过名称(car_data)传递反应性本身,而不读取它(car_data())。 callModule(linkedScatter,"scatters",car_data) 这类似于如何通过名称将函数传递给类似于lapply的东西: 适用(字母,触摸)#工作 (字母,触摸器())#不起作用

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48592056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档