Как отобразить код в модуле shiny, передав переменную среды?

#r #shiny

#r #блестящий

Вопрос:

Я пытаюсь отобразить пользовательский интерфейс из ввода кода через блестящие модули. Но я не могу понять, почему это не работает. Ошибок нет, поэтому трудно понять, где нарушается реактивность.

Код

 library(shinyAce)
library(reactlog)

reactlog_enable()

codeUI <- function(id) {
  ns <- NS(id)
  tagList(htmlOutput(ns("output")))
}

codeSE <- function(id, active_id, code, env) {
  moduleServer(id,
               function(input, output, session) {
                 
                 output$output <- renderUI({
                   req(id == active_id(), cancelOutput = TRUE)
                   eval()
                   eval_code <- paste0("n```{r echo = TRUE, comment = NA}n", code(), "n```n")
                   HTML(knitr::knit2html(text = eval_code, fragment.only = TRUE, quiet = TRUE, env = env()))
                 })
             })
}

 ui <- fluidPage(
  htmlOutput("output"),
  aceEditor("code", mode = "r", height = "50px"),
  actionButton("eval", "Evaluate"),
  div(id = "#add_here")
)


env <- environment()
server <- function(input, output, session) {
  
  counter <- 1
      active_id <- reactiveVal()
      observeEvent(input$eval, {
    req(code)
      current_id <- paste0("out_", counter)
      active_id(current_id)
      codeSE(id = current_id, active_id = active_id, code = input$code, env = env)
     insertUI(selector = "#add_here",ui = codeUI(current_id))
      counter <<- counter   1
      runjs('
      document.getElementById("end").scrollIntoView();
    ')
})   } 
   shinyApp(ui, server)
 

Цель приложения — ввести код на входе и отобразить выходные данные в виде divs при нажатии кнопки evaluate.
введите описание изображения здесь

Ответ №1:

У вас было несколько проблем:

  • в div , id должно быть add_here , нет #add_here . # In insertUI предназначен для jQuery
  • env это обычная переменная, а не функция. Так что env вместо env()
  • когда вы вызываете свой модуль, вы используете code = input$code . Это означает, что вы передаете оцененный реактивный, поэтому он больше не реагирует. Поэтому вам нужно использовать code вместо code() в вашем модуле
 library(shinyAce)
library(shinyjs)
library(shiny)

codeUI <- function(id) {
  ns <- NS(id)
  tagList(htmlOutput(ns("output")))
}

codeSE <- function(id, active_id, code, env) {
  moduleServer(id,
               function(input, output, session) {
                 
                 output$output <- renderUI({
                   req(id == active_id(), cancelOutput = TRUE)
                   eval_code <- paste0("n```{r echo = TRUE, comment = NA}n", code, "n```n")
                   HTML(knitr::knit2html(text = eval_code, fragment.only = TRUE, quiet = TRUE, envir = env))
                 })
               })
}

ui <- fluidPage(
  htmlOutput("output"),
  aceEditor("code", mode = "r", height = "50px"),
  actionButton("eval", "Evaluate"),
  div(id = "add_here")
)


env <- environment()
server <- function(input, output, session) {
  
  counter <- 1
  active_id <- reactiveVal()
  observeEvent(input$eval, {
    req(code)
    current_id <- paste0("out_", counter)
    active_id(current_id)
    codeSE(id = current_id, active_id = active_id, code = input$code, env = env)
    insertUI(selector = "#add_here",ui = codeUI(current_id))
    counter <<- counter   1
    runjs('
      document.getElementById("end").scrollIntoView();
    ')
  })   } 
shinyApp(ui, server)