Comments (6)
This is a good example of why the team should consider introducing an additional effect
signature or another function named differently (e.g. watch
) that provides the ability to specify dependencies explicitly and does not track the effect callback execution. Implicit dependency tracking looks nice and powerful, but when it comes to more complex cases, an explicit array/sequence of dependencies seems 'safer' and more predictable:
watch(this.isPopoverVisible, (isVisible) => {
if (isVisible) {
this.openPopover();
} else {
this.destroyPopover();
}
});
Btw, VueJS provides both options via watch
(explicit) and watchEffect
(implicit dependency tracking) functions.
from angular.
This is working as expected. openPopover
executes the popover template inside the effect
which adds any signals in the template to the effect. You need to wrap openPopover
inside an untracked
call to prevent this: https://stackblitz.com/edit/github-kphkvx?file=src%2Fmain.ts,src%2Fapp%2Fbroken-popover.component.ts,src%2Fapp%2Fpopover-directive.ts,src%2Fapp%2Fworking-popover.component.ts
from angular.
tl;dr for anyone following along:
When creating a view (e.g. through CDK Overlay) inside an effect
function, this effect
function will track any signals inside the created view.
The current solution is to create this view inside an untracked(() => { ... })
function:
// Template passed into a view that will be instantiated
<ng-template #templateRef>
{{ someSignal() }}
</ng-template>
// Effect that either instantiates or destroys the view
createViewEffect = effect(() => {
if (this.isPopoverVisible()) {
// When wrapping with `untracked`, we ensure that this effect does not track signals inside the view
untracked(() => this.openPopover());
} else {
this.destroyPopover();
}
});
openPopover() {
const templateRef = this.templateRef();
// Create an embedded view using this template
...
}
from angular.
Note that this isn't exactly as expected - one of the reasons effect
is still developer preview is that its interaction with different framework APIs is still a work in progress. In particular, it's an open question whether Angular should untrack all rendering operations by default, or throw errors if you accidentally call them from reactive contexts, or just run the operations like it does today.
from angular.
Understood! Thank you Andrew & Alex for providing a workaround, and for providing feedback on this issue. 😄 🙏
Glad to work with the current behaviour for the time being, since as you mentioned effect
is in dev preview.
My personal feeling is that the current behaviour is unexpected as it adds a hard to debug pitfall that's not immediately noticeable (IE: devs expect effects
callbacks only to run when a tracked signal changes).
The other options you mentioned both sound like valid paths to me (I'm curious about other developers' experience/opinions around either). Excited to follow along. 😄
Feel free to repurpose/close this issue as desired!
from angular.
I would prefer error and opt-in through options flag like with allowSignalWrites
.
Same would be good if someone calls an Output-EventEmitter inside an effect()
.
from angular.
Related Issues (20)
- addEventListener with AbortSignal option can cause memory leaks HOT 1
- API reference list link missing. HOT 2
- The sentence on the document confuses me HOT 2
- TypeScript Infinity and NaN errors HOT 2
- provideClientHydration() shouldn't cache HttpClient GET requests with "Authorization" header HOT 2
- @Input({ required: true }) - Required inputs do not throw errors at build time HOT 4
- Doc is contradictory about :host vs @HostBinding and @HostListener HOT 3
- compiler: cryptic error when the track expression is empty for the control flow @for HOT 1
- Add an observable that get triggered when the number of control changes in the FormArray. HOT 3
- [adev] CLI command pages options are cluttered HOT 1
- CLI sub commands are not listed correctly in adev HOT 3
- Aliases for Angular CLI options are not listed in adev HOT 1
- Deprecated CLI options are not marked as such in adev HOT 1
- Aliases for Angular CLI commands are not listed in adev HOT 1
- ADEV is missing illustration on `ng completion`
- Support for setting Input Signals programmatically for projected content children HOT 8
- Components with *ngIf are rendered before others HOT 5
- document.createElement('canvas') fails out of the box HOT 4
- Getting started tutorial does not seem to work HOT 2
- Broken Link on Angular.IO HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from angular.