两个以上的相关选择会导致无限循环

问题描述 投票:0回答:1

在下面的简单示例中,我在选择状态 1 和 2 后无法选择状态 3。它在 2 个状态下工作正常,但一旦我进入三个状态,它就会无限循环观察事件。如果它是更新的触发器,我希望它在仅选择第一个状态后无限循环,但事实并非如此。

我遇到了 freezeReactiveValue() 函数,但是当我冻结反应值以尝试不运行observeEvent时,选择不会更新以防止用户两次选择相同的状态。

有什么想法吗?

STATES <- c("AL", "AK", "AZ", "AR", "CA", "CO", "CT",
            "DE", "DC", "FL", "GA", "HI", "ID", "IL",
            "IN", "IA", "KS", "KY", "LA", "ME", "MD",
            "MO", "MT", "NE", "NV", "NH", "NJ", "NM",
            "NY","NC", "ND", "OH", "OK", "OR", "PA",
            "PR", "RI", "SC", "SD", "TN", "TX", "UT",
            "VT", "VA", "VI", "WA", "WV", "WI", "WY")
ui <- fluidPage(fluidRow(
  selectizeInput("state1", label = "State", 
                 choices = STATES,
                 selected = NULL,
                 multiple = FALSE,
                 options = list(placeholder = "Select a State",
                                onInitialize = I('function() { this.setValue(""); }'))),
  
  selectizeInput("state2", label = "State", 
                 choices = STATES,
                 selected = NULL,
                 multiple = FALSE,
                 options = list(placeholder = "Select a State",
                                onInitialize = I('function() { this.setValue(""); }'))),
  
  selectizeInput("state3", label = "State", 
                 choices = STATES,
                 selected = NULL,
                 multiple = FALSE,
                 options = list(placeholder = "Select a State",
                                onInitialize = I('function() { this.setValue(""); }')))
))

server <- function(input, output, session) ({
  observeEvent(input$state1, {
    updateSelectizeInput(
      session, "state2",
      choices = setdiff(STATES,
                        c(input$state1, input$state3)),
      selected = input$state2
    )
    updateSelectizeInput(
      session, "state3",
      choices = setdiff(STATES,
                        c(input$state1, input$state2)),
      selected = input$state3
    )
  })
  
  observeEvent(input$state2, {
    updateSelectizeInput(
      session, "state1",
      choices = setdiff(STATES,
                        c(input$state2, input$state3)),
      selected = input$state1
    )
    updateSelectizeInput(
      session, "state3",
      choices = setdiff(STATES,
                        c(input$state1, input$state2)),
      selected = input$state3
    )
  })
  
  observeEvent(input$state3, {
    updateSelectizeInput(
      session, "state1",
      choices = setdiff(STATES,
                        c(input$state2, input$state3)),
      selected = input$state1
    )
    updateSelectizeInput(
      session, "state2",
      choices = setdiff(STATES,
                        c(input$state1, input$state3)),
      selected = input$state3
    )
  })
  
  
})

shinyApp(ui = ui, server = server)
shiny selectize.js
1个回答
0
投票

正如您已经注意到的,

onInitialize = I('function() { this.setValue(""); }')
会导致无限循环,因为每次
updateSelectizeInput
运行时都会调用它。

作为替代方案,您可以执行以下操作:由于启动应用程序时

selectizeInput
的值应设置为
""
,您也可以在
choices = NULL
内设置
ui
。这将自动将初始值设置为
""
。为了使
STATES
的元素可选,请将它们放入服务器内的
reactiveVal

states <- reactiveVal(STATES)

并设置

choices
updateSelectizeInput
参数,使其使用
states()
:

choices = setdiff(states(), c(input$state1, input$state3))

请注意,对于下面的 MWE,我还更正了您上次

updateSelectizeInput
中的假定拼写错误(设置
selected = input$state2
而不是
input$state3
)。

STATES <- c("AL", "AK", "AZ", "AR", "CA", "CO", "CT",
            "DE", "DC", "FL", "GA", "HI", "ID", "IL",
            "IN", "IA", "KS", "KY", "LA", "ME", "MD",
            "MO", "MT", "NE", "NV", "NH", "NJ", "NM",
            "NY","NC", "ND", "OH", "OK", "OR", "PA",
            "PR", "RI", "SC", "SD", "TN", "TX", "UT",
            "VT", "VA", "VI", "WA", "WV", "WI", "WY")

ui <- fluidPage(fluidRow(
    selectizeInput(
        "state1",
        label = "State",
        choices = NULL,
        selected = NULL,
        multiple = FALSE,
        options = list(placeholder = "Select a State")
    ),
    
    selectizeInput(
        "state2",
        label = "State",
        choices = NULL,
        selected = NULL,
        multiple = FALSE,
        options = list(placeholder = "Select a State")
    ),
    
    selectizeInput(
        "state3",
        label = "State",
        choices = NULL,
        selected = NULL,
        multiple = FALSE,
        options = list(placeholder = "Select a State")
    )
))

server <- function(input, output, session)
    ({
        states <- reactiveVal(STATES)
        
        observeEvent(input$state1, {
            updateSelectizeInput(
                session,
                "state2",
                choices = setdiff(states(),
                                  c(input$state1, input$state3)),
                selected = input$state2
            )
            updateSelectizeInput(
                session,
                "state3",
                choices = setdiff(states(),
                                  c(input$state1, input$state2)),
                selected = input$state3
            )
        })
        
        observeEvent(input$state2, {
            updateSelectizeInput(
                session,
                "state1",
                choices = setdiff(states(),
                                  c(input$state2, input$state3)),
                selected = input$state1
            )
            updateSelectizeInput(
                session,
                "state3",
                choices = setdiff(states(),
                                  c(input$state1, input$state2)),
                selected = input$state3
            )
        })
        
        observeEvent(input$state3, {
            updateSelectizeInput(
                session,
                "state1",
                choices = setdiff(states(),
                                  c(input$state2, input$state3)),
                selected = input$state1
            )
            updateSelectizeInput(
                session,
                "state2",
                choices = setdiff(states(),
                                  c(input$state1, input$state3)),
                selected = input$state2
            )
        })
        
    })

shinyApp(ui = ui, server = server)
© www.soinside.com 2019 - 2024. All rights reserved.