2015-07-06 17 views
5

Giả sử chúng tôi có một bộ tiện ích con với nhãn đầu vào của riêng chúng. Làm cách nào để tạo đối tượng phản ứng có giá trị là ký tự đại diện cho ID đầu vào của tiện ích con cuối cùng đã được sửa đổi?Tạo biến phản ứng sáng bóng cho biết tiện ích nào được sửa đổi lần cuối

Ví dụ, nếu chúng ta có

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 
    }) 
}) 

Các kết quả mong muốn là như sau. Nếu người dùng sửa đổi hộp văn bản đầu tiên, thì giá trị của last_updated_widget() sẽ là "txt_a". Nếu họ sửa đổi hộp thứ hai, giá trị của last_updated_widget() sẽ trở thành "txt_b". Tôi đang tìm kiếm một kết quả mở rộng đến sự khái quát hóa rõ ràng về việc thiết lập giá trị là ID của bất kỳ tiện ích nào đã được điều chỉnh cuối cùng.

Tôi muốn tính năng này hoạt động với số lượng đầu vào tiện ích tùy ý, bao gồm cả trường hợp chúng được tạo bởi tuyên bố renderUI(). Vì vậy, thực hiện một tuyên bố riêng biệt reactive() cho mỗi widget không phải là một lựa chọn. Tuy nhiên, nếu câu lệnh phản ứng đòi hỏi một vòng lặp trên tất cả các tên widget (hoặc một cái gì đó như thế) tôi chắc chắn có thể làm việc với điều đó. Và nhiều câu trả lời là không sao, miễn là nó là một số tiền cố định, và không phải là một hàm số của các widget.

Dường như đây là một vấn đề khá đơn giản, vì vậy tôi đã rất ngạc nhiên khi nó trở thành rào cản đối với tôi. Tôi cảm thấy như giải pháp sẽ thực sự rõ ràng và tôi chỉ không nhìn thấy, vì vậy nếu có, tôi xin lỗi vì đã biến nó thành một câu hỏi mới. Nhưng bất kỳ trợ giúp sẽ được đánh giá rất nhiều.

Trả lời

7

Dưới đây là một giải pháp mà làm việc, mặc dù nó trông giống một chút lúng túng vì một lồng nhau observe(). Tôi không chắc chắn một cách tốt hơn sẽ là gì, nhưng có thể có một cái gì đó đẹp hơn. Về cơ bản, sử dụng một observe() để lặp qua tất cả các đầu vào có sẵn và cho mỗi đầu vào, sử dụng observe() khác sẽ chỉ kích hoạt khi đầu vào đó được thay đổi và đặt biến thành id của đầu vào.

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

Bạn có thể sử dụng giá trị phản hồi được tạo với reactiveValues() để lưu trữ tên của tiện ích được sử dụng gần đây nhất. Sau đó sử dụng một người quan sát để theo dõi hoạt động của mỗi widget và cập nhật giá trị phản ứng với tên của widget được sử dụng cuối cùng.

Trong ví dụ folowing, tên của tiện ích được sử dụng cuối cùng được lưu trữ trong last_updated_widget$v và sẽ hoạt động verbatimTextOutput mỗi lần thay đổi. Bạn có thể sử dụng last_updated_widget$v tại bất kỳ vị trí nào trong máy chủ.

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

Tôi không nghĩ anh ấy/cô ấy muốn một giải pháp thủ công như thế, câu hỏi ban đầu nói rằng họ nên owrk với một số tùy ý các đầu vào –

+0

daatali là đúng, nhưng tôi thay đổi nội dung chi tiết đó vào câu hỏi. Nếu Geovany đã trả lời trước khi tôi chỉnh sửa nó, tôi xin lỗi – Bridgeburners

+1

Tôi xin lỗi, tôi đã viết mã mẫu trước khi bạn cập nhật câu hỏi, vì vậy tôi đã không nhận thấy hạn chế và chỉ dán mã. Tính năng đó sẽ hữu ích, có lẽ sẽ tốt hơn nếu làm việc nội bộ với lõi sáng bóng. Nhân tiện @daattali thư viện shinyjs của bạn là rất hữu ích. – Geovany

Các vấn đề liên quan