3

I have a HomePage page with a property shouldNavBeTransparent: boolean = true which indicates if the navbar of the page should have a class="transparent or not.

After the window has reached 90% of its height, I set the property shouldNavBeTransparent to true.

My problem is that the property isn't being changed in the view. In the view, it's always false, while in the component, it's being changed.

This is my home.ts file:

import {Component} from '@angular/core';
import {IonicPage} from 'ionic-angular';

@IonicPage({segment: "/"})
@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
})
export class HomePage {

  services: Array<{ icon: string, title: string, subhead: string, content: string }>;

  shouldNavBeTransparent: boolean = true;

  scrollHandler($event) {
    this.shouldNavBeTransparent = ($event.scrollWidth * 0.9) < $event.scrollTop;
    console.log(this.shouldNavBeTransparent);
  }
}

The console.log in scrollHandler outputs true and false, which indicates it is changing: indicating the property is being changed

The part where I check the property in my view is (home.html):

<ion-header [class.transparent]="shouldNavBeTransparent">

The part where I trigger the scroll event:

<ion-content (ionScroll)="scrollHandler($event)">

Even when I write {{ shouldNavBeTransparent }} all I get is true.


I'm using Ionic v3.19.1

Melchia
  • 22,578
  • 22
  • 103
  • 117
Eliya Cohen
  • 10,716
  • 13
  • 59
  • 116
  • How do you set `scrollHandler` as the scroll event handler? – ConnorsFan Mar 10 '18 at 16:13
  • @ConnorsFan thanks for the reply. I've edited the question. You can see how I set the scroll event now. – Eliya Cohen Mar 10 '18 at 16:17
  • Shouldn't it be `$event.scrollHeight * 0.9` instead of `$event.scrollWidth * 0.9`? – ConnorsFan Mar 10 '18 at 16:29
  • No it shouldn't. Still, the statement is reached so it doesn't matter. – Eliya Cohen Mar 10 '18 at 16:33
  • in `home.scss`. It's applied always (since I can't solve this issue) which means, It exists and it works – Eliya Cohen Mar 10 '18 at 16:41
  • It looks as if Angular does not perform change detection when the event is triggered. You can try: `this.changeDetectorRef.detectChanges();` after setting `shouldNavBeTransparent` in the event handler. – ConnorsFan Mar 10 '18 at 16:41
  • @Melchia - If it was a CSS issue, `{{ shouldNavBeTransparent }}` would display the correct value. – ConnorsFan Mar 10 '18 at 16:47
  • One more question: we see in the console that the flag value changes. In your output image, the last value is `true`. Can you scroll in such a way that the last value in the console is `false`? – ConnorsFan Mar 10 '18 at 16:56
  • @ConnorsFan, yea. I just scrolled top and bottom for the fun. I'm checking your solution with the detection. – Eliya Cohen Mar 10 '18 at 16:58
  • @ConnorsFan looks like your solution works. But it still makes me wonder why it happens? – Eliya Cohen Mar 10 '18 at 17:02

2 Answers2

1

You can use ngClass to assign classes conditionally:

<div [ngClass]="{'yourclass':yourcondition}">

For your specific problem:

<ion-header [ngClass]="{'transparent':shouldNavBeTransparent}">

Edit:

import { ChangeDetectorRef } from '@angular/core';

constructor (private ref: ChangeDetectorRef) {}

scrollHandler($event) {
    this.shouldNavBeTransparent = ($event.scrollWidth * 0.9) < $event.scrollTop;
    this.ref.detectChanges();
}

this.ref.detectChanges(); should manually update your variable.

Stephan Strate
  • 1,401
  • 1
  • 12
  • 15
1

After doing some research I found that you need to use ngZone.

Scroll events happen outside of Angular's Zones. This is for performance reasons. So if you're trying to bind a value to any scroll event, it will need to be wrapped in a zone.run()

import { Component, NgZone } from '@angular/core';
 constructor( public zone: NgZone){}
scrollHandler($event) {
   this.zone.run(()=>{
     // the update needs to happen in zone
    this.shouldNavBeTransparent = ($event.scrollWidth * 0.9) < $event.scrollTop;
    console.log(this.shouldNavBeTransparent);
   })
Melchia
  • 22,578
  • 22
  • 103
  • 117
  • 1
    This is the answer I was looking for. Detect for changes will solve my problem too, but your answer is more precise. Therefore, I accept this answer. Thanks! – Eliya Cohen Mar 10 '18 at 17:08