我有一个反应式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
无效,因此它安排了重新执行。
答案 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。