2016-04-16 9 views
2

Ich möchte eine Schaltfläche, um eine Aktion auf eine vordefinierte nicht reaktive Variable x auslöst. Jedes Mal, wenn die Taste gedrückt wird, wird x <- x + 1 ausgeführt. Um zu überprüfen, ob es korrekt durchgeführt wurde, sollte das Ergebnis angezeigt werden. Um dies zu erreichen, habe ich versucht observeEvent(). Aber es macht nur einmal was es soll. Wie funktioniert es richtig?Aktion Schaltfläche und beobachtenEvent

Es scheint, dass rv nur innerhalb der observeEvent() Funktion verfügbar ist. Wenn output$text_2 <- renderText({ rv$a }) außerhalb von observeEvent() platziert wird, tritt ein Fehler auf. Wie kann ich etwas außerhalb von observeEvent() getanes verwenden?

library(shiny) 
x <- 0 

ui <- fluidPage(

    actionButton(inputId = "action", 
       label = "action"), 
    textOutput("text_1"), 
    textOutput("text_2") 

) 

server <- function(input, output) { 

    output$text_1<- renderText({ input$action }) 

    observeEvent(input$action, { 
       x <- x + 1 
       rv <- reactiveValues(a = x) 
       output$text_2 <- renderText({ rv$a }) 
       }) 
} 

shinyApp(ui = ui, server = server) 
+4

Sie müssen verstehen, wie Scoping in R arbeitet und in glänzend. Die Variable 'x' wird in diesem Fall niemals geändert (sie wird bei jedem Drücken der Taste auf 1 gesetzt, aber nur die lokale Kopie von' x' wird auf 1 gesetzt, die globale Version bleibt 0). Und ein weiterer Fehler ist, dass 'rv' innerhalb der Serverfunktion definiert werden sollte, aber außerhalb des Beobachters. Denn gerade jetzt definieren Sie die 'rv'-Variable jedes Mal neu, wenn der Beobachter läuft. Sie sollten Artikel zum Thema Scoping in R und in Shiny (zwei separate Themen) lesen. –

Antwort

1

Daattalis Antwort ist genau das Richtige, aber ich dachte ich einige Beispiele posten könnte, wie Sie Shinys reaktive Werte verwenden können, dies zu tun.

library(shiny) 

ui <- fluidPage(

    actionButton(inputId = "action", 
       label = "action"), 
    textOutput("txt_example1"), 
    textOutput("txt_example2"), 
    textOutput("txt_example3") 

) 

server <- function(input, output) { 

    # ------------------ Example 1 ------------------ 
    # Use a list of reactive values 
    rv <- reactiveValues(x=0) 

    # Will update text output when rv$x is updated 
    observe({ 
    output$txt_example1 <- renderText({ rv$x }) 
    }) 


    # ------------------ Example 2 ------------------ 
    # Make variable a reactive 
    x <- 0 
    makeReactiveBinding('x') 

    # The only 'trick' here is that x is made a reactive so that the observer is 
    # triggered every time x is updated. 
    # If x is not made a reactive the value of x will still be updated but the observer 
    # wont trigger (see example 3). 

    observe({ 
    output$txt_example2 <- renderText({ x }) 
    }) 

    # ------------------ Example 3 ------------------ 
    # Use ordinary R scoping 

    x2 <- 0 

    printUpdate <- function(){ 
    output$txt_example3 <- renderText({ x2 }) 
    } 

    printUpdate() # Print first value 

    # onClick listener, same for all examples 
    observeEvent(input$action, { 
    rv$x <- rv$x + 1 # Example 1, update reactive list 
    x  <<- x + 1 # Example 2, Save x to parent enviroment 

    # Example 3 
    x2 <<- x2 + 1  # Again, save x2 to parent enviroment, see help('<<-') 
    printUpdate()  # Update textOutput 
    }) 


} 

shinyApp(ui = ui, server = server) 

Hoffe, das hilft!

+0

Dies ist sehr "unsinnig", um eine Ausgabe in einem 'beobachten' zu ändern. Sie würden eine Ausgabe normalerweise nur einmal mit einem reaktiven Ausdruck festlegen, wobei das Rezept die Ausgabe jedes Mal aktualisieren soll, wenn sie als veraltet betrachtet wird –

1

Ab 2017 gibt es einen einfacheren, besseren Weg, dies mit zu tun:

library(shiny) 

ui <- fluidPage(
    actionButton("go", "Click me"), 
    helpText("All values in the table below are incremented ", 
    "each time you press the button"), 
    verbatimTextOutput("tbl") 
) 

server <- function(input, output, session) { 
    x <- reactiveVal(1) 

    observeEvent(input$go, { 
    x(x() + 1) 
    }) 

    output$tbl <- renderPrint({ 
    x() 
    }) 
} 

shinyApp(ui, server) 
Verwandte Themen