Getting Packery / Masonry to work with angular2
Asked Answered
A

1

6

I'm trying to get Packery / Masonry to work on a component. Packery is detecting the container but giving it a height of zero suggesting the content hasn't loaded even though I'm using imagesLoaded. I've tried using various lifecycle hooks but they all have the same result so bit lost as to where I'm going wrong.

import {BlogService} from './blog.service';
import {Blog} from './blog.model';
import {Component, ElementRef, OnInit, AfterViewInit} from '@angular/core';
import {LinkyPipe} from '../pipes/linky.pipe';

declare var Packery: any;
declare var imagesLoaded: any;

@Component({
  moduleId: module.id,
  selector: 'blog',
  templateUrl: 'blog.component.html',
  providers: [BlogService],
  pipes: [LinkyPipe]
})

export class BlogComponent implements OnInit, AfterViewInit {
  blogs: Blog[];
  errorMessage: string;
  constructor(private _blogService: BlogService, public element: ElementRef) { }
  ngOnInit() {
    this.getBlogs();
  }

  ngAfterViewInit() {
    let elem = this.element.nativeElement.querySelector('.social-grid');
    let pckry;
    imagesLoaded(elem, function(instance) {
      console.log('loaded');
      pckry = new Packery(elem, {
        columnWidth: '.grid-sizer',
        gutter: '.gutter-sizer',
        percentPosition: true,
        itemSelector: '.social-card'
      });
    });
  }

  getBlogs() {
    this._blogService.getPosts()
      .subscribe(
      blogs => this.blogs = blogs,
      error => this.errorMessage = <any>error);
  }
}
Ampereturn answered 11/5, 2016 at 10:6 Comment(0)
A
3

Ok I worked it out that I needed to use AfterViewChecked instead however when I first tried it ended up it a never ending loop as this is fired every time the DOM changes so as you'll see there are a few extra checks in place so it only fires once. Still not sure if it's the correct way to do it but it works for now.

import {BlogService} from './blog.service';
import {Blog} from './blog.model';
import {Component, ElementRef, OnInit, AfterViewChecked} from '@angular/core';
import {LinkyPipe} from '../pipes/linky.pipe';
declare var Packery: any;
declare var imagesLoaded: any;
@Component({
  moduleId: module.id,
  selector: 'coco-blog',
  templateUrl: 'blog.component.html',
  providers: [BlogService],
  pipes: [LinkyPipe]
})
export class BlogComponent implements OnInit, AfterViewChecked {
  blogs: Blog[];
  errorMessage: string;
  isGridInitialized: boolean;
  constructor(private _blogService: BlogService, public element: ElementRef) { }
  ngOnInit() {
    this.getBlogs();
  }
  ngAfterViewChecked() {
    if (this.blogs && this.blogs.length > 0 && !this.isGridInitialized) this.initGrid();
  }
  getBlogs() {
    this._blogService.getPosts()
      .subscribe(
      blogs => this.blogs = blogs,
      error => this.errorMessage = <any>error);
  }
  initGrid() {
    this.isGridInitialized = true;
    let elem = document.querySelector('.social-grid');
    let pckry;
    imagesLoaded(elem, function(instance) {
      console.log('all images are loaded');
      pckry = new Packery(elem, {
        percentPosition: true,
        itemSelector: '.social-card',
        gutter: 20
      });
    });
  }
}
Ampereturn answered 13/5, 2016 at 8:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.