Closed nevir closed 9 years ago
@jmesserly It'd be great to get this fixed. Would you mind reviewing? Thanks!
Also, I'm having a hell of a time writing a test case to repro this (since the {{foo in foos}}
syntax isn't directly supported by this lib) - leaving that out for now
(looking)
hmmm. Yeah, agree with you, I'm not sure about reading value_ like that. It looks like the code is designed to handle if and repeat on the same template, e.g. like this test https://github.com/Polymer/TemplateBinding/blob/master/tests/tests.js#L592 ... if we fail to call discardChanges() to compute the most recent value, it might not do the right thing for a combined if/repeat case. (Although none of the tests seem to catch that.)
Possibly what needs to happen here is to split updateIteratedValue into two methods, one that is called when ifValue changes and one that is called when repeatValue changes. That way we can recompute the other (if needed) without recomputing the value that was just delivered to us.
FYI, a test can probably be done using a custom bindingDelegate, e.g. https://github.com/Polymer/TemplateBinding/blob/master/tests/tests.js#L2620
btw @nevir I'm happy to dig into this more if you'd like & help out with testing. Let me know!
fyi, think I have an updated version, working on tests to cover the new cases & the ones I was worried about regressing.
[edit: ignore this, see next comment]
hmmm. Thinking on this more, I wonder if we should try mitigate this from the ObserverTransform side too. It could avoid calling getValueFn if `this.observable.discardChanges()returned the same value. That would require one extra field on ObserverTransform, but it has the benefit that anyone using it doesn't need to be careful about calling discardChanges triggering too much recomputation. Otherwise, we have to be really careful to avoid discardChanges calls when we already know the value (e.g. because it was just handed to us via
open`)
oops, we can't mitigate this in ObserverTransform.discardChanges because we'd need deep equality (expensive). Thanks to the "reduce" test case for reminding me of this :)
My alternate approach is in https://github.com/Polymer/TemplateBinding/pull/180 ... appreciate your thoughts and comments
Fixes #174
However, before this is committable:
ObserverTransform#value_
seems wrong. Should I add anObserverTransform#getValue
?Also, this raises a related question:
Why does this work?
TemplateIterator#updateDependencies
, we create andopen
theObserverTransform
for the filtered value.ObserverTransform
reads the value of the function inopen
updateDependencies
->updateIteratedValue
.updateIteratedValue
, we read the value via discardChanges; which causes the function to be called again.