ngxtension / ngxtension-platform

Utilities for Angular
https://ngxtension.netlify.app/
MIT License
600 stars 87 forks source link

hostBinding with class doesn't remove previous classes correctly #468

Closed evantrimboli closed 2 months ago

evantrimboli commented 2 months ago

Consider the following code:

export class PlaygroundComponent {
  readonly value = model('cool');
  constructor() {
    hostBinding('class', this.value);
    setTimeout(() => {
      this.value.set('not-cool');
    }, 5000);
  }
}

On first render, the class 'cool' will be correctly applied. However, after the timer runs, the class on the host element will be 'cool not-cool'.

I'm pretty sure the issue is here: https://github.com/ngxtension/ngxtension-platform/blob/5ccebef244cbc3ae81bec3518a90d9a9987269e6/libs/ngxtension/host-binding/src/host-binding.ts#L47

prevClasses needs to be declared outside of the effect, otherwise it's getting overwritten each run.

ajitzero commented 2 months ago

Your suggested usage isn't supported afaik. hostBinding itself returns a signal that should be used to update it. See docs: https://ngxtension.netlify.app/utilities/components/host-binding/

So:

readonly value = hostBinding('class', signal('cool'));

constructor() {
  setTimeout(() => {
    this.value.set('not-cool');
  }, 5000);
}
evantrimboli commented 2 months ago

Looking at the source code it returns the same signal that is passed in.

Also as I said above, prevClasses is declared inside the effect, so it's going to be overwritten each time.