Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Packery with Angular 2

I can't seem to get Packery working with Angular 2 using angular-cli and typescript 2.0. I'm using Packery 1.4.1 and the typescript definitions for that version from DefinitelyTyped.

The issue is that the Packery reference to Outlayer cannot be found when running the project with ng serve.

Specifically the following exception is thrown due to that:

TypeError: Cannot set property 'position' of undefined at Object.utils.extend (eval at webpackJsonp.82.module.exports

Below is my code for the project.

Scripts section from angular-cli.json:

"scripts": [
        "../node_modules/packery/dist/packery.pkgd.js"],

I have also tried adding the dependent js files but the exception thrown is the same:

"scripts": [
        "../node_modules/packery/dist/packery.pkgd.js",
        "../node_modules/get-size/get-size.js",
        "../node_modules/outlayer/outlayer.js",
        "../node_modules/ev-emitter/ev-emitter.js",
        "../node_modules/fizzy-ui-utils/utils.js",
        "../node_modules/desandro-matches-selector/matches-selector.js"
        ],

app.component.ts:

import { Component, ViewChild, AfterViewInit } from '@angular/core';
declare var Packery: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit
{
  @ViewChild('grid') grid;

  private pckry: any;
  constructor() {}

  ngAfterViewInit(){
    this.pckry = new Packery(this.grid, {
      itemSelector: '.grid-item'});
  }
}

app.component.html

<div #grid class="grid">
  <div class="grid-item"></div>
  <div class="grid-item"></div>
</div>

I would like help on how to get Packery to run in Angular 2 with or without typings (vanilla js would be ok for me).

like image 807
Mikael Kristensen Avatar asked Feb 09 '17 15:02

Mikael Kristensen


1 Answers

The issue with the above was that I did not use the "nativeElement" property of the grid. This will work:

var packery = new Packery(this.grid.nativeElement, {
itemSelector: '.grid-item', columnWidth: 100 });

Also the only script needed in the scripts section of angular-cli is the following:

"scripts": [
        "../node_modules/packery/dist/packery.pkgd.js"        
        ]

To add draggability use "npm install draggability --save" and add another script to the scripts section of angular-cli:

"scripts": [
        "../node_modules/packery/dist/packery.pkgd.min.js",
        "../node_modules/draggabilly/dist/draggabilly.pkgd.min.js"        
        ]

Then update the component class as well:

import { Component, ViewChild, AfterViewInit } from '@angular/core';
declare var Packery: any;
declare var Draggabilly: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit
{      
  @ViewChild('grid') grid;   

  constructor() {}

  ngAfterViewInit(){
      var packery = new Packery(this.grid.nativeElement, {
        itemSelector: '.grid-item', columnWidth: 100 });

      packery.getItemElements().forEach( function( itemElem ) {
        var draggie = new Draggabilly( itemElem );
        packery.bindDraggabillyEvents( draggie );
      });         
  }
}
like image 78
Mikael Kristensen Avatar answered Sep 17 '22 11:09

Mikael Kristensen