New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Computed properties (model => model synchronisation) #47553
Comments
I would strongly vote agains React's Deps should be collected automatically just like in the majority of reactive frameworks/libs. |
@th0r the memoization approach was listed in the "alternatives" section as something you can do today to achieve similar effects. It is not part of the actual proposal. |
Ah, ok, sorry then. |
In my opinion, having a decorator that turns an input into an observable would be fantastic. It would:
Or with a more realistic example:
The only point I can think of that'd need a bit more thinking would be how to get an equivalent of And with this, would come the question of being type safe etc. A possible alternative to that solution (for the previous example) would be something like:
|
I think any discussion of a reactivity system in Angular needs to consider more than computed properties. What if a child component injects a parent component with computed properties? Can a service have computed properties? What about parameterised computed properties? What about computed properties for content and view queries? How do we call effects reactively based on any property (or computed property)? Vue uses proxy objects to achieve this. With decorators you can swap the Vue has a composition API. This lets you group related logic together with hooks for initializing and tearing down effects. In Angular this could be achieved with a configurable @Component()
export class UIComponent {
@Input() userId!: string
todos: Todo[] = []
// memoized until `todos` changes
@Select() get remaining() {
return this.todos.filter(todo => !todo.completed)
}
// this function runs in its own `EnvironmentInjector` context
// it is called on the first change detection run and whenever `userId` changes
// it can also be called imperatively
@Invoke() loadTodos() {
// dependency injection
const loadTodos = inject(HttpClient).get(endpoint, {
params: { userId: this.userId }
})
// hook for configuring merge strategy
useOperator(switchAll())
// run some effects
// each call cancels the previous effect (ie: switchAll)
dispatch(loadTodos, todos => {
this.todos = todos
})
}
} Reference: https://github.com/antischematic/angular-state-library |
I maintain an enterprise Angular application with more than 200 libraries and 60 component driven pages. We utilize almost every feature available in Angular, but the last thing I would want is application state managed by Angular itself. I found myself doing a lot of this type of thing:
So much so, that we developed a decorator to add in some sugar.
For 'computed properties', we just use I think rather than adding a "Computed Properties" DSL, using proxies or decorators to instruct change detection that fields have changed would be useful. Instead of a |
I think services can have computed properties - Javascript has class getters, and there are libraries such as |
I am missing a possibility to add an input transformer to
|
We do have computed properties with signals now! |
@pkozlowski-opensource would you share an example? |
Oh, you're right... my last comment was about observable inputs, so I got confused. You are right computed signals are the fix to this issue :) |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Which @angular/* package(s) are relevant/related to the feature request?
core
Description
Angular dirty-checking mechanism works well for synchronising (propagating) model changes to the DOM. However, there are legitimate situations where one would like to compute / derive a new model value (from the existing model values) before rendering. Angular has no such concept - even if requested by users (ex.: #20472).
Proposed solution
We don't have any concrete solution proposal at the moment but we are exploring the space and will open a RFC when the solution space becomes clearer. But even without the concrete proposal on a table, there are certain properties that we would like to see in the final solution:
@Input
- it should be possible to compute new model value based on input values changing over time;Alternatives considered
While Angular doesn't have the dedicated concept of the computed properties, there are several existing mechanisms that can serve the purpose (although with different caveats). Here is an overview of the possible approaches that work today.
Use an external reactivity system
Many Angular users integrate RxJS, or similar push-based reactivity systems, into their template rendering pipeline. Most (all?) of the push-based reactivity systems have a concept of deriving values (ex. combinelatest in RxJS).
Use memoization
We could introduce a simple
memo
utility function. A memo function could just compare previous / new arguments and execute re-computation when needed, similar to what the pure pipe does today. Ex. (taken from #46135):Here is a working stackblitz: https://stackblitz.com/edit/angular-ivy-txzpmf?file=src%2Fapp%2Fapp.component.ts,src%2Fapp%2Fmemo.ts
Existing issues / PRs
The idea of computed properties was discussed in the past in the issue tracker - most notably in #20472 (which generated number of comments and ~70 upvotes).
The text was updated successfully, but these errors were encountered: