binding: computedFrom doesn't support paths
It is my understanding and my experience that computedFrom
does not work with paths, like: @computedFrom('user.firstName')
.
I think that this is a very hard limitation that should be lifted:
- Modeling and using sub-properties is common once your application gets even moderately complex.
- There is sometimes no good alternative to
computedFrom
.
My use case is a computed property that creates an array from complex computations and lookups from other arrays. Definitively not something you want to poll and it is too complex for the auto-observation plugin. On the other hand its dependency is trivial to express as it is a single, nested property.
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 38 (20 by maintainers)
Commits related to this issue
- refactor(ExpressionObserver): add context/callable signature This is needed to support #149 — committed to aurelia/binding by jdanyow 8 years ago
+1 my own ticket along other people, just to attract attention here @EisenbergEffect
We’ve used Aurelia for 6 months in a complex project and there is something crucial missing; this might be part of the solution.
In UI you commonly have dependencies/computations between various elements. Some simple examples: list elements are filtered by other inputs (commonly just a textbox), you display the total of a shopping cart, you display shipping options only when the user did not choose “pickup” and is not in a foreign country, and so on.
A modern application needs to be able to express such values declaratively, as a computation from their dependencies:
I’ve used properties for all these examples, although there can be other representations.
Aurelia needs a good story for those use-cases.
It could be some good integration with Reactive programming patterns and/or libraries, which are suited for those kind of things (and more!). I think Rx is great for many advanced scenarios but maybe a little overboard for something as simple as the motivating examples I’ve shown here.
Coming from Knockout, the examples above would ‘just work’, thanks to the inherent capability of KO to automatically discover and watch the dependencies of any computations (method, property or otherwise).
To be honest, the examples above would also ‘just work’ in Aurelia because they would trigger dirty checking. It’s just that we need to be careful with dirty checking. Overusing it can lead to perf, battery or animation issues. Examples like the grand total can quickly become expensive to evaluate repeatedly. So we need to have another option.
@computedFrom
could be that tool but it only works for simple properties. That’s too limiting and if it is the only solution to this problem it needs to beef up: at least start with sub-properties and arrays support.I personally believe that this theme is very important to Aurelia and it’s really overdue.
Hi,
Can you provide an example of the use of computedFrom with dot property ?
I tried computedFrom(“MyObject.property”) but this does not work.
@EisenbergEffect I saw this plugin when it was fresh. I’m a bit wary of it. It’s leaning toward too much magic for my taste:
return
expressions;In the end, if you’re only going to use it for a few trivial computed properties, you might as well slap a
computedFrom
on them and be done. At least that’s how I feel vs the added complexity/bloat.Mind you, I love the idea and actually was asking for some automatic dependency tracking when I first got into Aurelia. Coming from KO, this was a very sweet feature. I have realized that this is not easy to build into the platform (not without read detection) and accepted that we might have to use manual dependency declaration instead.
@davismj You are nitpicking on the examples I gave. They were all made-up to illustrate and I agree some have alternate solutions. I have much more complex examples from real applications.
I agree the first two were very well suited to value converters. Especially because they are so re-usable across your app. Just imagine they’re not 😉
The last one works… until I tweak my model to:
get showShippingOptions() { return this.shippingMethod !== 'pickup' && this.shippingAddress.country === 'US'; }
And now it does not.Looking forward to your blog post BTW!