3

I'm trying to implement a MagnificPopup solution to a page full of images. Because they're rendered via an *ngFor, the code to initialise the popup functionality is run before the images have rendered.

Is there a way to run the code only when the view has finished rendering (or, even better, the view contents has changed)? I've seen ways to execute code when a component's @Inputs change, but not when its internal methods do.

user1381745
  • 3,850
  • 2
  • 21
  • 35
  • Whenever you have too many elements on a page you should use `changeDetectionStrategy.OnPush` to prevent lagging and crashing due to heavy load, for more, [see this similar question](http://stackoverflow.com/a/37088348/5612697) – Ankit Singh May 17 '16 at 13:01

2 Answers2

1

There is currently no built-in support.

You can make your internal fields that *ngFor is bound to setters and call methods when they're changed.

Using

set someValue(newValue) {
  this._someValue = newValue;
  setTimeout(() => afterValueChanged(),10);
}

should delay execution of afterValueChanged() enough for Angular being done updating the DOM. This way afterValueChanged() will be enqueued in the event queue and Angular should be done when this scheduled event queue task is actually executed.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
0

Solution (at least, as far as I can tell): ngAfterViewInit.

import {Component, AfterViewInit} from 'angular2/core';

export class Gallery implements AfterViewInit {

    ngAfterViewInit() {
        $('.gallery')['magnificPopup']({
            delegate: 'a',
            type: 'image',
            gallery: {
                enabled: true
            }
        });
    }
}

Irrelevant parts of the class ignored, obviously. The square bracket notation calling the method within ngAfterViewInit is needed because the TS compiler complains about missing properties (true at compile-time, but not runtime) when using dot notation.

user1381745
  • 3,850
  • 2
  • 21
  • 35
  • can it be that AfterContentInit is needed as it wont wait for the ngFor to be done? – eesdil Mar 15 '16 at 13:12
  • @eesdil Possibly - it (ngAfterViewInit) certainly appears to work for me thus far, but might not with a greater number of elements in the iterated array. – user1381745 Mar 15 '16 at 15:58