2016-09-25 23 views
5

Stworzyłem aplikację Shiny, która pobiera dane z bazy danych. Mam wiele danych wejściowych w części UI i wiele wyników w części Server.Zrozumienie funkcji reaktywnych w Shiny

W części serwerze mam reaktywną funkcję, która buduje zapytanie za pomocą niektórych wejść i wtedy ściąga dane z bazy danych, np:

queriedData <- reactive({ 
       query <- paste0(...,input$a,...); 
       return(db$find(query)) 
       }) 

w gniazdach wyjściowych, odsyłam do danych w użyciu

x <- queriedData() 

Moje pytania są następujące:

  • wierzę, że baza danych jest odpytywany tylko wtedy, gdy dane wejściowe są re do zmiany funkcji reaktywnej. Czy to jest poprawne?
  • W związku z tym, czy mam rację sądząc, że wywołanie tej funkcji reaktywnej nie powoduje odrodzenia zapytania - tj. Dane są buforowane, a dane z pamięci podręcznej są dostarczane?
  • W przypadku danych wejściowych, które nie są częścią kwerendy, zakładam, że zmiany w nich nie powodują nowego zapytania do bazy danych. Czy to jest poprawne?
+1

Wierzę, że twoje zrozumienie jest poprawne. Sposobem na przetestowanie jest umieszczenie niektórych instrukcji 'print()' w twoich funkcjach, aby zobaczyć, co zostanie uruchomione, kiedy. – SymbolixAU

+0

Myślę, że pierwsza kwestia jest nieco inna, wartość reaktywna zostanie unieważniona, gdy dane wejściowe będą zależały od zmiany, ale zostanie ona ponownie oceniona, gdy powiedzmy, że niektóre produkty, które wymagają aktualizacji, muszą zostać zaktualizowane. Obserwatorzy działają zgodnie z twoim pierwszym punktem. –

Odpowiedz

2

Aby odpowiedzieć na Twoje pytania:

  1. Rzeczywiście, każdy reaktywny wyrażenie jest przedłużane tylko wtedy, gdy jedna z reaktywnych wyrażeń to zależy od niego jest aktualizowana. Shiny robi to, aby przekazać flagę unieważniającą, gdy wartość wyrażenia reaktywnego zmienia się na wszystkie inne wyrażenia reaktywne, które od niego zależą. Następnym razem, gdy używane są unieważnione wyrażenia reaktywne, są one ponownie obliczane. Tak więc w twoim przypadku queriedData (co jest wyrażeniem reaktywnym) zostanie unieważnione, a zatem aktualizowane za każdym razem, gdy otrzyma flagę unieważniającą z input$a. Ponieważ zapytanie bazy danych jest częścią tego obliczenia, twoje założenie jest poprawne.
  2. To zależy. Gdy input$a nie uległa zmianie, a zatem queriedData nie jest unieważniany, po prostu zwraca dane z pamięci podręcznej. Kiedy zmieniła się input$a, zmieniono ponownie queriedData, a tym samym odradza się zapytanie.
  3. Ponieważ tylko wyrażenia reaktywne mogą przekazać flagę unieważniającą, są to jedyne, które mogą w rzeczywistości spowodować ponowne obliczenie innego wyrażenia reaktywnego. Jeśli inne części nie są reaktywne, nie mogą również zostać unieważnione, a zatem nie mogą spowodować ponownego przeliczenia queriedData.

Należy pamiętać, że wyrażenie reaktywne niekoniecznie musi być wejściem. Weźmy następujący przykład:

query <- reactive({paste0(...,input$a,...)}) 
queriedData <- reactive({ 
       db$find(query()) 
       }) 
output$thedata <- renderDataTable(queriedData()) 

Teraz zmiana input$a unieważnia query, powodując jej przeliczenie. query, wyrażenie reaktywne, unieważni queriedData(), powodując jego ponowne obliczenie. Spowoduje to unieważnienie output$thedata, a zatem spowoduje również ponowne obliczenie tej części, co spowoduje, że nowe dane zostaną wyświetlone w tabeli danych.