Giter VIP home page Giter VIP logo

Comments (6)

markostanimirovic avatar markostanimirovic commented on June 5, 2024 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.

atscott avatar atscott commented on June 5, 2024 4

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.

kfrancois avatar kfrancois commented on June 5, 2024 3

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.

alxhub avatar alxhub commented on June 5, 2024 1

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.

kfrancois avatar kfrancois commented on June 5, 2024

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.

mikezks avatar mikezks commented on June 5, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.