1

I create Slides based on a condition. When the condition is true the Slides component is initialized.

<ion-slides *ngIf="condition === true">
  <ion-slide *ngFor="let question of questions">
    // slide content
  </ion-slide>
</ion-slides>

Addionally I disable swipe by setting onlyExternal = true. Since this is not an input property I have to set the value in the parent component's ngAfterViewInit method.

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

@Component{
  ...
}
export class QuizPage implements AfterViewInit {
  @ViewChild(Slides) slides: Slides;
  ...
  ngAfterViewInit {
    this.slides.onlyExternal = true;
  }
  ...
}

When the view condition changes the Slides-component gets destroyed and looses the onlyExternal setting. It gets initialized again when the condition is fulfilled, but ngAfterViewInit is only called once, when the parent component is initialized. Which means the onlyExternal setting is not set.

Currently I use ngAfterViewChecked, but it gets called quite often, I was wondering if there is a better way to solve this problem.

ngAfterViewChecked() {
  if(this.slides) {
    this.slides.onlyExternal = true;
  }
}

2 Answers2

0

User ViewChildren and subscribe to change notification.

Here is an example https://plnkr.co/edit/jZBWR6Y4afqhV9g020k2

  @Component({
    selector: 'my-app',
    template: `
      <div>
        <button (click)="toggleHello()">Toggle Hello</button>
        <h2 #vc *ngIf="show">Hello {{name}}</h2>
      </div>
    `,
  })
  export class App {
    show = true;
    @ViewChildren('vc') h2: QueryList<ElementRef>;

    name:string;
    constructor() {
      this.name = `Angular! v${VERSION.full}`
    }

    toggleHello() {
      this.show = !this.show;
    }

    ngAfterViewInit() {
      this.setAttr();
      this.h2.changes.subscribe(()=> {
        this.setAttr();
      }
    }

    setAttr() {
      if(this.show) {
           this.h2.toArray()[0].nativeElement.style['color']= 'blue';
        }
    }
  }
Julia Passynkova
  • 17,256
  • 6
  • 33
  • 32
  • This usually works, but not when inside an `*ngIf` block. When the if-condition is not fulfilled the component inside the if gets destroyed. Therefore @ViewChildren is `undefined`. When it is available again the subscription is not active any more. – Matthias Tylkowski May 16 '17 at 07:25
  • i am not sure that i understood you. i use ngIf with ViewChildren in this example. Please show me you html structure to help. – Julia Passynkova May 16 '17 at 11:09
  • Everything is included in my question. `...` is the component that I access with `@ViewChild(Slides) slides: Slides;`. When the `condition` is `false` `@ViewChild(Slides)` is `undefined`. Therefore `subscribe` does not work. – Matthias Tylkowski May 16 '17 at 11:38
  • try to use @ViewChild with descendants: true and put ViewChild on top – Julia Passynkova May 16 '17 at 12:02
  • I could not find a `descendants: true` setting for `@ViewChild` – Matthias Tylkowski May 16 '17 at 12:56
0

I finally found the solution on another question: angular-2-viewchild-in-ngif

A setter has to be used on the @ViewChild. That one will only called once, when the ngIf condition changes.

export class QuizPage {
  private slides: Slides;
  @ViewChild(Slides) set slidesViewChold(slides: Slides) {
    if(slides) {
      slides.onlyExternal = true;
    }
    this.slides = slides;
  }
  ...
}