基于(布尔)反应性条件

时间:2019-03-13 15:20:25

标签: r shiny

我有一个反应式rv和一个反应式布尔值rv.haschanged,其定义如下:

rv <- reactive({
  rv.haschanged()

  rv.haschanged(FALSE)

  cars[sample.int(nrow(cars), 1),] # return cars dataset as an example
})

rv.haschanged <- reactiveVal(FALSE)

例如,现在有一些观察者可以将rv.haschanged设置为TRUE

observe({
    # do something...

    rv.haschanged(TRUE)
})

我想要的是rv仅在rv.haschanged更改为TRUE时才更新自身(而不是在rv.haschanged更改为FALSE时更新)。上面的代码的问题在于它将rv更新两次。观察者执行rv.haschanged(TRUE)之后,一次是由于rv.haschanged(FALSE)而造成的。

是否有任何简洁直观的习惯来实现以上目标?

编辑:基本上,我想要做的只是使观察者中的rv无效,因此它安排了重新执行。

2 个答案:

答案 0 :(得分:1)

执行所需操作的最佳方法是isolate在反应式表达式中rv.haschanged的所有用法,以免它们使表达式无效,然后使用可以包含逻辑的中间反应性值你想要的。

我们将使用名为rv.haschanged()的新反应式值,而不是使用check中的更改来使您的反应式表达式无效,该值仅包含一个计数器,该计数器在rv.haschanged更改且为{{ 1}}

TRUE

现在,我们可以使用check <- reactiveVal(0) observeEvent(rv.haschanged(), if (rv.haschanged() == TRUE) check(check() + 1)) 在反应式表达式中隔离rv.haschanged()

isolate

或将其更改为rv <- reactive({ check() isolate(rv.haschanged(FALSE)) cars[sample.int(nrow(cars), 1),] # return cars dataset as an example }) ,其作用类似于eventReactive,但隔离了reactive内部的所有内容:

valueExpr

这有点骇人听闻,但据我所知,无法短路反应式表达式的无效性:它是有效的(未更改)或无效的(已更改)。在处理闪亮代码时,对我有用的是将反应性表达式分解为较小的块(尤其是当它们包含耗时的任务时),以最大程度地减少在无效的情况下必须重新运行的代码量。

答案 1 :(得分:0)

这有效:

rv <- eventReactive(rv.haschanged(), {      
  rv.haschanged(NULL)

  cars[sample.int(nrow(cars), 1),] # return cars dataset as an example
})

rv.haschanged <- reactiveVal(NULL)

观察者:

observe({
    # do something...

    rv.haschanged(TRUE)
})

这利用了ignoreNULL = TRUE的{​​{1}}选项。因此,我们使用eventReactive而不是使用FALSE

请注意,此will not work if multiple objects are put in the eventExpr argument