I have implemented Owl Carousel 2 in my angular2 app with much success until now. The carousel clones items in order to create a loop effect. This is great until you need to perform a click event on the item and the event doesn't fire. There is a work around in the docs, that I found at this SO question. I've modified the JSFiddle from that SO question to show that the workaround works in way that I'm using the carousel in my app. Unfortunately this only solves the problem if your not using Angular 2.
The workaround script is fairly simple:
$('#carousel').on('click', '.item', function () {
alert("click");
;})
Because of the modular nature of Angular2 and that it discourages direct dom manipulation I can't just throw this in my js files and it works. I have to add it to a component. The question is which component and how do get the dom element refernce of the carousel.
There is a great SO answer here that shows how to use the Owl Carousel with angular2. I modified the Plunker from that question to show how I'm using the carousel in my app and to experiment with ways of solving this problem with the cloned items.
Basically I have 2 Components:
//our root app component
import { Component, AfterViewInit } from 'angular2/core';
import { OwlCarousel } from './owl-carousel.component';
@Component({
selector: 'app',
directives: [OwlCarousel],
template: `
<div *ngFor="#carousel of carousels" let i = index;>
<h3>{{carousel.title}}</h3>
<owl-carousel [options]="{loop: true, margin: 5}" id= {{carousel.title}}>
<div *ngFor="#img of carousel.images">
<img src="http://lorempixel.com/400/200/{{img.href}}"/>
<button class='imagebutton'(click)=getImage(img.id) >Select image {{img.id}}</button>
</div>
</owl-carousel>
<button (mouseenter)="over(carousel.title)" (mouseleave)="leave(carousel.title)" id="prev1" class="btn prev">Previous</button>
</div>
`
})
export class App {
elment: any = {};
carousels = [
{
title: 'caro1',
images:[
{id:'1', href: 'sports'},
{id:'2', href: 'abstract'},
{id:'3', href: 'people'},
{id:'4', href: 'transport'},
{id:'5', href: 'city'},
{id:'6', href: 'technics'},
{id:'7', href: 'nightlife'},
{id:'8', href: 'animals'}
]
},
{
title: 'caro2',
images:[
{id:'1', href: 'food'},
{id:'2', href: 'cats'},
{id:'3', href: 'business'},
{id:'4', href: 'fashion'},
{id:'5', href: 'nature'},
{id:'6', href: 'transport'},
{id:'7', href: 'abstract'},
{id:'8', href: 'technics'}
]
}
]
intr: any;
owl: any;
getImage(id){
alert('You selected image' +id);
}
over(title) {
console.log(title);
this.intr = setInterval(() => {this.movePrevious(title)}, 500);
};
leave(){
clearInterval(this.intr);
};
movePrevious(title) {
console.log("elment: " + title);
this.owl = $('#'+ title).owlCarousel();
this.owl.trigger('prev.owl.carousel');
};
ngAfterViewInit() {
$('#caro1').on('click', '.item .imagebutton', function () {
alert("click");
});
}
}
You can see there at the bottom in the ngAfterViewInit() I put the workaround code and used the carousel element id to reference it. I'm pretty sure this doesn't work because of the way angular2 works so I tried using angulars ElementRef module (like I do in the code for the owl-carousel component below) but I could not get it to work in that component or the owl-carousel component below.
import { Component, Input, ElementRef, HostBinding } from 'angular2/core';
import $ from 'jquery';
import 'owl-carousel';
@Component({
selector: 'owl-carousel',
template: `
<ng-content></ng-content>
`
})
export class OwlCarousel {
@HostBinding('class') defaultClass = 'owl-carousel';
@Input() options: object;
$owlElement: any ={};
defaultOptions: any = {};
constructor(private el: ElementRef) {}
ngAfterViewInit() {
if(this.options === null){
this.options = this.defaultOptions
}
this.$owlElement = $(this.el.nativeElement).owlCarousel(this.options);
$(this.el.nativeElement).on('click', '.item .imagebutton', function () {
alert("click");
});
}
ngOnDestroy() {
this.$owlElement.data('owlCarousel').destroy();
this.$owlElement = null;
}
}
I have tried a few different variations, moving the workaround code between the two components with no success. I even tried .find() like this:
$(this.el.nativeElement).find('#caro1').on('click', '.item .imagebutton', function () {
alert("click");
});
Anyone have a clue as to how to implement this workaround for angular2?