peerlibrary / meteor-computed-field

Reactively computed field for Meteor
https://atmospherejs.com/peerlibrary/computed-field
BSD 3-Clause "New" or "Revised" License
18 stars 6 forks source link

Calling computed field from event triggers recomputation. #9

Closed MatejJan closed 8 years ago

MatejJan commented 8 years ago

Here is a simple reproduction:

@test = new ComputedField =>
  console.log "I'm being called."

$(document).keypress =>
  @test()

This will trigger recomputation (seen by the console.log) on every keypress.

A simple workaround (which is how I thought this would behave) is:

@test = new ReactiveField null

Tracker.autorun =>
  @test console.log "I'm being called."

$(document).keypress =>
  @test()

So is this by design or a bug? I'm only experiencing recomputation from events (or timeout/interval) and also only on the first call (if I call test() multiple times, it's recomputed only the first time).

mitar commented 8 years ago

Is @test defined inside an autorun? If not, I think computed field detects that and stops autorun to cleanup and prevent you from having a runaway autorun?

https://github.com/peerlibrary/meteor-computed-field/blob/master/lib.coffee#L21

MatejJan commented 8 years ago

I did this test in onCreatedof a component … so I guess not? Is this bad? Maybe this should be in the constructor then.

mitar commented 8 years ago

No, onCreated should be good. The issue here is that it is cleaning up because you never used it inside reactive context. Probably this should be configurable.

MatejJan commented 8 years ago

I think I understand. It tries to help so you don't have to manually call stop() from onDestroyed, right? But then, since it's not running, it has to recompute itself to make sure it has the latest value.

Although if this is true, it means most of the time when I was using ComputedFields they were not really running reactively at all, but simply reevaluating each time.

MatejJan commented 8 years ago

Maybe inside a component you could call @test = new @ComputedField … which uses template's @autorun instead. ;)

mitar commented 8 years ago

See #5 for more information about better integration with templates.

mitar commented 8 years ago

With 35947c5382f241daab7743cad1f26fcc68e94251 you can also use second argument to prevent automatic stopping:

@test = new ComputedField =>
  console.log "I'm being called."
,
  true
mitar commented 8 years ago

With 0.5.0 version I made it so that computed field inside onCreated is still automatically stopped even when automatic stopping because of no dependency is disabled. The following will stop @test automatically after template is destroyed, but will not stop the computed field if you are using computed field only inside events.

@test = new ComputedField =>
  console.log "I'm being called."
,
  true