3

I'm using Ionic 2, which sits on top of Angular 2. I would like to have a class added to my ion-header element. This is to allow me to have the header have a transparent background initially, but a solid background on scroll.

I am setting a variable in my Typescript file, and updating that variable when the user scrolls.

I need to set the class based on the variable in my Typescript variable. I have done this elsewhere in my app with [ngClass]="{showBack: navBack}" but this doesn't seem to work on this page.

Typescript:

import { Component, ViewChild } from '@angular/core';
import { Content } from 'ionic-angular';

@Component({
  selector: 'page-class',
  templateUrl: 'class.html'
})
export class ClassPage {
  @ViewChild(Content)
  content: Content;
  navBack: boolean = false;

  constructor(...){}

  ngAfterViewInit() {
    this.content.ionScroll.subscribe((event) => {
      if(event.scrollTop == 0) {
        this.navBack = false;
      } else {
        this.navBack = true;
      }
    });
  }

}

HTML:

<ion-header [ngClass]="{showBack: navBack}">
  <ion-navbar>
    <ion-title>Test</ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <p style="height: 300px">Long page of content here.</p>
  <p style="height: 300px">Long page of content here.</p>
  <p style="height: 300px">Long page of content here.</p>
</ion-content>

I would expect to see a showBack CSS class on my ion-header which appears on scroll, however it never appears, regardless of the value of event.scrollTop.

I have done some debugging with console.logs on the ngAfterViewInit function, and I can confirm the variable is being changed correctly, but the class does not update.

1

2 Answers 2

2

Shouldn't it be:

[ngClass]="{'showBack': navBack}"

(you're missing single quotes)

Sign up to request clarification or add additional context in comments.

3 Comments

Quite possibly - I've tried it, but the class still does not appear. Likewise, if I default the value to true in my Typescript it always shows and is not updated by the ionScroll.subscribe event (which is definitely being called).
Wierd, why not try [class.showBack]="navBack" - which is often used when working with a single class
Nope - same with that too. I have put it on a div as well, just in case ion-header had some odd functionality on it preventing class manipulation, but it's the same deal there. It seems that changes made in the Typescript aren't updating the variable in the view.
1

In order for something to trigger change detection it needs to be executed within Angular’s zone.

import { Component, ViewChild, NgZone } from '@angular/core';
import { Content } from 'ionic-angular';

@Component({
  selector: 'page-class',
  templateUrl: 'class.html'
})
export class ClassPage {
  @ViewChild(Content)
  content: Content;
  navBack: boolean = false;

  constructor(private ngZone: NgZone){}

  ngAfterViewInit() {
    this.content.ionScroll.subscribe((event) => {
      this.ngZone.run(() => {
          if(event.scrollTop == 0) {
            this.navBack = false;
          } else {
            this.navBack = true;
          }
    });
   });
}

}

2 Comments

That's fixed it. Can you explain what the issue here was? It's a bit confusing, because this.navBack was updating, just not updating the view, so what is ngZone doing?
Somehow ionScroll code leaves Angulars zone and breaks change detection. So we are triggering change detection manually using ngZone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.