2016-09-25 2 views
1

복잡한 Shiny 앱이 있습니다. 출력물이 selectize이고 selectTest인데,이 값은 반응 형 객체 인 isTestReady에 의해 읽혀집니다. isTestReady은 특정 조건이 selectTest을 만족하는지 평가합니다. 그런 다음 isTestReady은 여러 청크에서 게이트로 사용됩니다. selectTestoutputOptions(suspendWhenHidden = F, priority 999)으로 설정하여 즉시 실행되도록했습니다.Reactive Chunk를 강제 평가하기

실행 중에는 selectTest에 대한 청크가 먼저 실행됩니다. 이 후에 isTestReady이 실행되면 첫 번째 청크에 selectTest에 할당 된 값이 아닌 selectTest의 값을 NULL로 계속 읽습니다. Shiny는 다시 돌아 오기 전에 다른 많은 모듈을 통해 isTestReady을 재평가합니다. 재평가 후에 다른 청크가 다시 호출되고 이제는 정상적으로 실행됩니다.

예상되는 동작입니까? 그렇다면 내 시나리오를 어떻게 묘사하는 방식에 대한 아이디어가 있습니까?

예 -

library(shiny) 
library(shinydashboard) 


# Setup Shiny app UI components ------------------------------------------- 

ui <- dashboardPage(

    dashboardHeader(), 
    ## Sidebar content 
    dashboardSidebar(
     sidebarMenu(
     uiOutput('someelement'), 
     textOutput('temp2') 
    ) 
    ), 
    dashboardBody() 

) 


# Setup Shiny app back-end components ------------------------------------- 

server <- function(input, output) { 

    output[['someelement']] = renderUI({ 
     selectizeInput(
     inputId = 'someelement', 
     choices = letters, 
     selected = letters[1], 
     label = 'Custom Functions', 
     multiple = F 
    ) 
    }) 

    outputOptions(
     output, 
     'someelement', 
     suspendWhenHidden = F 
    ) 

    temp = reactive({ 
     print('?') 
     input[['someelement']] 
    }) 

    observe({ 
     print('!') 
     print(temp()) 
    }) 

    output[['temp2']] = renderText({ 
     print('!!') 
     print(temp()) 
     '-' 
    }) 

} 

# Render Shiny app -------------------------------------------------------- 

shinyApp(ui, server) 

다음과 같이 위의 응용 프로그램에 대한 콘솔에 로그 출력을 보면 -

[1] "!" 
[1] "?" 
NULL 
[1] "!!" 
NULL 
[1] "!" 
[1] "?" 
[1] "a" 
[1] "!!" 
[1] "a" 

이 NULL을 피하기 위해 어떤 방법을? 내 응용 프로그램에는 temp()을 찾는 청크가 많이 있는데, 모두 temp() 전에 실행됩니다.

+0

하지만 해결책처럼 보일 것 - http://stackoverflow.com/questions/30378310/shiny-renderui-selectinput-returned-null?rq=1에게 당신은 바인딩 할 수 있습니다 – TheComeOnMan

+1

'eventReactives'도 다른 반응들과 함께 사용합니다. 이렇게 :'eventReactives {temp(), {}}'. 또한 거기에 여러개를 넣을 수도 있습니다 –

+0

@ PorkChop,'temp()'를 기반으로 새로운 출력 객체를 만들고 있으므로'eventReactive'는 옵션이 아닙니다. 지저분한 '지역'사업 등을하지 않는 한. – TheComeOnMan

답변

0

observe() 및 reactiveValues ​​()를 사용해보십시오. this question에 대한 허용 대답을 참조하십시오. reactive()는 게으름입니다.

텍스트의 변수 이름이 코드와 일치하도록 질문이 편집되었습니다. 하지만 나는 네가 그리워 할 수도 있겠지. 이 같은?

library(shiny) 
library(shinydashboard) 


# Setup Shiny app UI components ------------------------------------------- 

ui <- dashboardPage(

    dashboardHeader(), 
    ## Sidebar content 
    dashboardSidebar(
    sidebarMenu(
     uiOutput('ui_selectTest') 
    ) 
), 
    dashboardBody() 

) 


# Setup Shiny app back-end components ------------------------------------- 

server <- function(input, output) { 

    rv<- reactiveValues() 

    output$ui_selectTest = renderUI({ 
    selectizeInput(
     inputId = 'selectTest', 
     choices = letters, 
     selected = letters[1], 
     label = 'Custom Functions', 
     multiple = F 
    ) 
    }) 

    observe(
    if(!is.null(input$selectTest)) { 
     #check select test 
     rv$testReady <- input$selectTest 
    } 
) 

    observeEvent(rv$testReady,{ 
    print( rv$testReady ) 
    }) 
} 

shinyApp(ui, server) 
+0

감사합니다. 이 제안은 내가 언급 한 링크와 비슷합니다. – TheComeOnMan

0

반응식 청크마다 validate을 사용하여 필요한 모든 입력 및 조건을 확인하십시오. 서버 기능은 다음이

server <- function(input, output) { 

    output[['someelement']] = renderUI({ 
    selectizeInput(
     inputId = 'someelement', 
     choices = letters, 
     selected = letters[1], 
     label = 'Custom Functions', 
     multiple = F 
    ) 
    }) 

    outputOptions(
    output, 
    'someelement', 
    suspendWhenHidden = F 
) 

    temp = reactive({ 
    #check if someelement is a valid input 
    validate(need(input[['someelement']] %in% letters, "need input")) 
    print('?') 
    input[['someelement']] 
    }) 

    observe({ 
    #check if tmp() has already been evaluated 
    validate(need(temp(), "need tmp")) 
    print('!') 
    print(temp()) 
    }) 

    output[['temp2']] = renderText({ 
    validate(need(temp(), "need tmp")) 
    print('!!') 
    print(temp()) 
    '-' 
    }) 

} 
관련
+0

감사합니다. 이것은 유망 해 보입니다. 내 앱에서 한번 확인해 보겠다. (하루나 이틀 정도 소요될 수있다.) 나는 그것이 작동하면 대답을 표시 할 것입니다. – TheComeOnMan

+0

나는 기본적으로 temp의 NULL 값 때문에 observe chunk의 나머지 부분의 실행을 차단하고 실제로 temp의 평가를 강제하지 않는다고 느낀다. – TheComeOnMan

관련 문제