2015-07-06 1 views
5

Предположим, у нас есть набор виджетов, каждый со своей собственной меткой ввода. Как создать реактивный объект, значением которого является символ, который представляет идентификатор ввода последнего виджета, который был изменен?Создание Блестящая реактивная переменная, которая указывает, какой виджет был последним изменен

Например, если мы имеем

ui.R

shinyUI(fluidPage(
    textInput('txt_a', 'Input Text A'), 
    textInput('txt_b', 'Input Text B") 
)) 

server.R

shinyServer(function(input, output) { 
    last_updated_widget <- reactive({ 
     #hypothetical code that indicates ID value of last updated widget 
    }) 
}) 

Желаемый результат заключается в следующем. Если пользователь изменяет первое текстовое поле, то значение last_updated_widget() будет "txt_a". Если они изменяют второй блок, значение last_updated_widget() становится "txt_b". Я ищу результат, который распространяется на очевидное обобщение установки значения как идентификатора любого из виджета, который был настроен последним.

Я бы хотел, чтобы это работало для произвольного количества входов виджетов, включая случай, когда они были сгенерированы оператором renderUI(). Поэтому отдельный оператор reactive() для каждого виджета не является вариантом. Однако, если реактивный оператор требует петли над всеми именами виджетов (или что-то в этом роде), я могу с этим работать. И несколько реактивных утверждений в порядке, если это фиксированная сумма, а не функция количества виджетов.

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

ответ

7

Вот решение, которое работает, хотя это выглядит немного неудобно из-за вложенной observe(). Я не уверен, какой будет лучший способ, но может быть что-то приятнее.

В принципе, используйте observe() для подключения всех доступных входов, а для каждого входа используйте другой observe(), который будет запускаться только тогда, когда этот вход будет изменен, и установите переменную на идентификатор входа.

runApp(shinyApp(
    ui = shinyUI(
    fluidPage(
     textInput('txt_a', 'Input Text A'), 
     textInput('txt_b', 'Input Text B'), 
     uiOutput('txt_c_out'), 
     verbatimTextOutput("show_last") 
    ) 
), 
    server = function(input, output, session) { 
    output$txt_c_out <- renderUI({ 
     textInput('txt_c', 'Input Text C') 
    }) 

    values <- reactiveValues(
     lastUpdated = NULL 
    ) 

    observe({ 
     lapply(names(input), function(x) { 
     observe({ 
      input[[x]] 
      values$lastUpdated <- x 
     }) 
     }) 
    }) 

    output$show_last <- renderPrint({ 
     values$lastUpdated 
    }) 
    } 
)) 
0

Вы можете использовать реактивное значение, созданное с помощью reactiveValues(), чтобы сохранить имя последнего использованного виджета. Позже используйте наблюдателя для отслеживания активности каждого виджета и обновления реактивного значения с именем последнего используемого виджета.

В приведенном ниже примере имя последнего использованного виджета хранится в last_updated_widget$v и будет активировать verbatimTextOutput каждый раз, когда он будет изменен. Вы можете использовать last_updated_widget$v в любом месте на сервере.

library(shiny) 
    runApp(list(
     ui = shinyUI(
      fluidPage(
       textInput('txt_a', 'Input Text A'), 
       textInput('txt_b', 'Input Text B'), 
       verbatimTextOutput("showLast") 
      ) 
     ), 
     server = function(input, output, session) { 
      last_updated_widget <- reactiveValues(v = NULL) 
      observe ({ 
       input$txt_a 
       last_updated_widget$v <- "txt_a" 
      }) 
      observe ({ 
       input$txt_b 
       last_updated_widget$v <- "txt_b" 
      }) 
      output$showLast <- renderPrint({ 
       last_updated_widget$v 
      }) 
     } 
    )) 
+1

Я не думаю, что он/она хочет вручную решения, как это, оригинальный вопрос говорит, что это должно owrk с произвольным числом входов –

+0

daatali является правильным, но я редактировал эту деталь в вопрос. Если Geovany уже отвечал, прежде чем я его отредактировал, я извиняюсь – Bridgeburners

+1

Прошу прощения, я написал образец кода, прежде чем вы обновили вопрос, поэтому я не заметил ограничения и просто вставлял код. Эта функция была бы полезна, возможно, лучше работать внутри с блестящим ядром. Кстати, @daattali ваша библиотека shinyjs очень полезна. – Geovany

Смежные вопросы