0

I am trying to apply a thick shadow to the toolbar when the user scrolls. I see scrollOffsetTop change in the console, but ngClass is not detecting the change and applying the class heavy-shadow when the value is greater than 0.

Why is ngClass not detecting the change?

<mat-toolbar [ngClass]="{'heavy-shadow': scrollTopOffset > 0, 'toolbar': true }">

export class AppComponent implements AfterViewInit {
   @ViewChild('snav') public snav: MatSidenav;
   @ViewChild('sideNavContent') public sideNavContent: MatSidenavContent;

  mobileQuery: MediaQueryList;
  private _mobileQueryListener: (media) => void;

  @Input()
  public scrollTopOffset:Number = 0;

  constructor(
    private changeDetectorRef: ChangeDetectorRef,
    private media: MediaMatcher) {
      this.mobileQuery = this.media.matchMedia('(max-width: 1000px)');
  }

  runScroller() {
    const scroller = this.sideNavContent.elementScrolled();

    scroller.subscribe({
      next: () => {
        this.scrollTopOffset = this.sideNavContent.measureScrollOffset('top');
        console.log(this.scrollTopOffset); // THIS CHANGES SUCCESSFULLY, I VERIFIED IN CONSOLE
      },
      error(msg) {
        console.log(msg);
      },
    });
  }
Rachid O
  • 13,013
  • 15
  • 66
  • 92
dman
  • 10,406
  • 18
  • 102
  • 201
  • there doesn't seem to be wrong anything..can you create a stackblitz example? – Shadab Faiz Jun 11 '20 at 01:09
  • Found out why, I had to run ` this.changeDetectorRef.detectChanges();`. Shouldn't this of been automatic where I didn't need to run that? – dman Jun 11 '20 at 01:16
  • How is `runScroller` called? – ConnorsFan Jun 11 '20 at 02:05
  • 1
    @dman, please take a look at the answer to this question. https://stackoverflow.com/questions/38445670/angular-2-view-will-not-update-after-variable-change-in-subscribe – Julian W. Jun 11 '20 at 02:56
  • @pindev, his problem is different from that referred question. – julianobrasil Jun 11 '20 at 04:01
  • @dman it should have run automatically unless you have specified it to not run. Check if there is anywhere you have used code like this: "ChangeDetectionStrategy.onPush()" – Shadab Faiz Jun 11 '20 at 04:53

1 Answers1

3

You should change the entire object that is being assigned to ngClass in order to get the change detection being fired. Mutating the object is not enough.

Instead of:

<mat-toolbar [ngClass]="{'heavy-shadow': scrollTopOffset > 0, 'toolbar': true }">

You can do:

<mat-toolbar [ngClass]="_toolbarStyle">

and in your ts class:

get _toolbarStyle(): {[key: string]: boolean} {
  return {
    'heavy-shadow': this.scrollTopOffset > 0, 
    'toolbar': true
  };
}

By doing that you'll be setting ngClass with a brand new object (with a different reference) every time scrollTopOffset changes.

julianobrasil
  • 8,954
  • 2
  • 33
  • 55
  • your answer would be correct if you ar echecking the object, however when using variable with primitive type like number or boolean directly, that will also work. – Shadab Faiz Jun 11 '20 at 04:55