Reputation: 41
I am trying to implement owl-carousel into my Angular 2 app.
I followed this example How to use owl-carousel in Angular2? and it actually works well with the only problem that my items are async change (ng-content async change).
By implementing the solution on plnkr when the content of my owl-courosel changes (promoter or detractor), the plugin doesn't reload. So I see just a list of the items but they do not scroll.
So I have nps-comments.component.html where the carousel component is called:
<section class="purchasers comments" *ngIf="comments.promoters.length || comments.detractors.length">
<carousel class="promoters" *ngIf="comments.promoters.length" [options]="{ items: 1 }">
<p *ngFor="let promoter of comments.promoters">{{promoter}}</p>
</carousel>
<carousel class="detractors" *ngIf="comments.detractors.length" [options]="{ items: 1 }">
<p *ngFor="let detractor of comments.detractors">{{detractor}}</p>
</carousel>
</section>
Then the actual carousel.component.ts
import {
Component,
Input,
ElementRef
} from '@angular/core';
import 'jquery';
import 'owl-carousel';
@Component({
moduleId: module.id,
selector: 'carousel',
templateUrl: 'carousel.component.html',
styleUrls: ['carousel.component.css']
})
export class CarouselComponent {
@Input() options: Object;
private $carouselElement: any;
private defaultOptions: Object = {};
constructor(private el: ElementRef) { }
ngAfterViewInit() {
for (let key in this.options) {
if (this.options.hasOwnProperty(key)) {
this.defaultOptions[key] = this.options[key];
}
}
let outerHtmlElement: any = $(this.el.nativeElement);
this.$carouselElement = outerHtmlElement.find('.owl-carousel').owlCarousel(this.defaultOptions);
}
ngOnDestroy() {
this.$carouselElement.trigger('destroy.owl.carousel');
this.$carouselElement = null;
}
}
And this is the carousel.component.html:
<div class="owl-carousel owl-theme">
<ng-content></ng-content>
</div>
Any help would be really appreciated. Thank you.
Upvotes: 3
Views: 4898
Reputation: 39
I am sharing my workaround of using owl [email protected] with angular 2.0.0 + webpack.
First you will need to install the above^ packages via npm or similar.
Then --> npm install imports-loader
(For using owl within component otherwise you will get function is undefined. Since third-party modules are relying on global variables like $ or this being the window object.).
I'm using webpack so this section is for webpack users:
imports-loader as follow:
{test: /bootstrap\/dist\/js\/umd\//, loader: 'imports?jQuery=jquery'}
Also u can use jQuery as (webpack):
var ProvidePlugin = require('webpack/lib/ProvidePlugin');
use as plugin:
plugins: [
new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery'
})
]
For images loader:
{
test: /\.(png|jpe?g|gif|ico)$/,
loader: 'file?name=public/img/[name].[hash].[ext]'
}
*public/img -- images folder
CSS loader:
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw'
}
The vendors.js file should import the following:
import 'jquery';
import 'owl.carousel';
import 'owl.carousel/dist/assets/owl.carousel.min.css';
Please be aware that owl.carousel 2 is still use andSelf() deprecated function of jQuery so we need to replace them with the new version of addBack().
Goto node_modules folder in the owl package dist/owl.carousel.js: replace all the occurrences of andSelf() with --> addBack().
Now is the angular 2 part:
owl-carousel.ts:
import {Component} from '@angular/core';
@Component({
selector: 'carousel',
templateUrl: 'carousel.component.html',
styleUrls: ['carousel.css']
})
export class Carousel {
images: Array<string> = new Array(10);
baseUrl: string = './../../../../public/img/650x350/';
}
carousel.component.ts:
import { Component, Input, ElementRef, AfterViewInit, OnDestroy } from '@angular/core';
@Component({
selector: 'owl-carousel',
template: `<ng-content></ng-content>`
})
export class OwlCarousel implements OnDestroy, AfterViewInit{
@Input() options: Object;
$owlElement: any;
defaultOptions: Object = {};
constructor(private el: ElementRef) {}
ngAfterViewInit() {
for (var key in this.options) {
this.defaultOptions[key] = this.options[key];
}
var temp :any;
temp = $(this.el.nativeElement);
this.$owlElement = temp.owlCarousel(this.defaultOptions);
}
ngOnDestroy() {
this.$owlElement.data('owlCarousel').destroy();
this.$owlElement = null;
}
}
carousel.component.html:
<owl-carousel class="owl-carousel"[options]="{navigation: true, pagination: true, rewindNav : true, items:2, autoplayHoverPause: true, URLhashListener:true}">
<div class="owl-stage" *ngFor="let img of images; let i=index">
<div class="owl-item">
<a href="#"><img src="{{baseUrl}}{{i+1}}.png"/></a>
</div>
</div>
</owl-carousel>
Make sure to bootstrap everything in the app.module:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import {OwlCarousel} from './components/carousel/carousel.component';
import {Carousel} from './components/carousel/owl-carousel';
@NgModule({
imports: [
BrowserModule,
NgbModule,
],
declarations: [
AppComponent,
OwlCarousel,
Carousel
],
providers: [appRoutingProviders],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Now you can use the directive/component in the entire app within the template/templateUrl section, no need to import anything.
Please follow the above since all the steps are necessary to complete the integration between angular 2.0.0 final release and owl.carousel 2.1.4 release.
Upvotes: 2