运行 javascript 为默认渲染方法渲染输出时的代码(如小部件的 onRender)

Run javascript code when output is rendered for default render methods (like onRender for widgets)

在闪亮的应用程序中,当使用 library(htmlwidgets) 中的 onRender 呈现小部件时,我们可以将 javascript 代码添加到 运行。对于闪亮的默认 render* 函数,这似乎不起作用。有没有办法为这些渲染函数实现类似的东西?

下面的应用程序会在渲染 plotly 和传单小部件时显示警报,但不会显示 renderUIrenderPlot

library(shiny)
library(plotly)
library(leaflet)
library(htmlwidgets)

ui <- fluidPage(
  actionButton('a1','a1'),
  fluidRow(
    column(
      width=6,
      plotlyOutput('plt'),
      plotOutput('p2')
    ),
    column(
      width=6,
      uiOutput('foo'),
      leafletOutput('map')
    )
  )
)

server <- function(input, output, session) {
  
  output$foo <- renderUI({
    input$a1
    tagList(runif(1)) %>% 
      onRender('function() {alert("renderUI works");}')
  })
  output$plt <- renderPlotly({
    input$a1
    plot_ly(type='scatter', mode='markers', x=runif(10)) %>% 
      onRender('function() {alert("plotly works");}')
  })
  output$p2 <- renderPlot({
    input$a1
    hist(runif(50)) %>% 
      onRender('function() {alert("renderPlot works");}')
  })
  output$map <- renderLeaflet({
    input$a1
    leaflet() %>% 
      addTiles() %>% 
      onRender('function() {alert("leaflet works");}')
  })
}

shinyApp(ui, server)

onRender 指的是渲染 htmlwidget 而不是 shiny 的 render* 函数。

你可以使用它without shiny

onRender 需要一个 HTML 小部件对象,因此不适用于例如标签 - 参见 ?onRender:

Use this function to supplement the widget's built-in JavaScript rendering logic with additional custom JavaScript code, just for this specific widget object.

您可以使用 library(shinyjs) 来实现类似的行为:

library(shiny)
library(plotly)
library(leaflet)
library(htmlwidgets)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  actionButton('a1','a1'),
  fluidRow(
    column(
      width=6,
      plotlyOutput('plt'),
      plotOutput('p2')
    ),
    column(
      width=6,
      uiOutput('foo'),
      leafletOutput('map')
    )
  )
)

server <- function(input, output, session) {
  output$foo <- renderUI({
    input$a1
    runjs('alert("renderUI works");')
    tagList(p("p-tag"))
  })
  output$plt <- renderPlotly({
    input$a1
    plot_ly(type='scatter', mode='markers', x=runif(10)) %>% 
      onRender('function() {alert("plotly works");}')
  })
  output$p2 <- renderPlot({
    input$a1
    runjs('alert("renderPlot works");')
    hist(runif(50))
  })
  output$map <- renderLeaflet({
    input$a1
    leaflet() %>% 
      addTiles() %>% 
      onRender('function() {alert("leaflet works");}')
  })
}

shinyApp(ui, server)