web-dev-qa-db-fra.com

Carrousel lisse avec Angular 2

Salut, je commence par Angular 2 et j'essaye de faire fonctionner ce plugin de carrousel: slick

Après un certain temps, j'ai réussi à le faire fonctionner comme un composant comme celui-ci:

import { Component, Input, ElementRef, AfterViewInit, AfterContentInit} from '@angular/core';
declare var jQuery: any;

@Component({
    selector: 'slick-slider',
    template: `
        <ng-content></ng-content>
    `
})
export class SlickSliderComponent implements AfterContentInit{
    @Input() options: any;

    $element: any;

    defaultOptions: any = {};

    constructor(private el: ElementRef) {
    }

    ngAfterContentInit() {
        for (var key in this.options) {
            this.defaultOptions[key] = this.options[key];
        }

        this.$element = jQuery(this.el.nativeElement).slick(this.defaultOptions);
    }
}

Et je l'utiliserais comme ceci sur un modèle:

<slick-slider>
    <div><img class="btn btn-lg" src="/assets/img/img1.png" /></div>
    <div><img class="btn btn-lg" src="/assets/img/img2.png" /></div>
    <div><img class="btn btn-lg" src="/assets/img/img3.png" /></div>
    <div><img class="btn btn-lg" src="/assets/img/img4.png" /></div>
    <div><img class="btn btn-lg" src="/assets/img/img5.png" /></div>
</slick-slider>

Cela fonctionne bien. Mais quand j'essaye de l'utiliser à l'intérieur de * ngFor comme ceci:

<slick-slider>
    <div *ngFor="let source of sources">
        <img class="btn btn-lg" (click)="watchSource(source)" src="/assets/img/{{source.name}}.png" />
    </div>
</slick-slider>

Cela cesse de fonctionner. Je suppose que c'est parce que l'init du curseur se fait avant le <div> les éléments sont en cours de rendu. Parce que je me retrouve avec ce HTML rendu:

<slick-slider class="slick-initialized slick-slider">
    <div>
      <img ... >
    </div>
    <div>
      <img ... >
    </div>
    <div>
      <img ... >
    </div>
    <div>
      <img ... >
    </div>

    <div aria-live="polite" class="slick-list draggable">
      <div class="slick-track" role="listbox" style="opacity: 1; width: 0px; transform: translate3d(0px, 0px, 0px);">
        <!-- Divs should be rendered here with slick styles included -->
      </div>
  </div>
</slick-slider>

Une idée comment faire pour que ça marche? J'ai essayé d'utiliser "ngAfterContentInit" et "ngAfterViewInit" ni l'un ni l'autre ne semble fonctionner.

Voici le composant utilisant le SlickSliderComponent:

import { Component, OnInit } from '@angular/core'
import { DeviceSource } from './device-source'
import { RemoteService } from './remote.service';

@Component({
    selector: 'device-selector',
    moduleId: module.id,
    templateUrl: 'device-selector.component.html',
    providers: []
})



export class DeviceSelectorComponent implements OnInit {

    sources: [DeviceSource];

    ngOnInit(): void {
        this.getDeviceSources();
    }

    constructor(private remoteService: RemoteService){}

    getDeviceSources(): void {
        this.remoteService.getDeviceSources().then(sources => this.sources = sources);
    }
}

Et voici le service utilisé:

import { Injectable } from '@angular/core'
import { DeviceSource } from './device-source'

export const DEVICE_SOURCES:[DeviceSource]=
[
    {id: 1, dispayName: 'TV', name:'tv'},
    {id: 2, dispayName: 'Chrome', name:'chrome'},
    {id: 3, dispayName: 'Cable', name:'cable'},
    {id: 4, dispayName: 'XBox', name:'xbox'},
    {id: 4, dispayName: 'Pi', name:'pi'},

];


@Injectable()
export class RemoteService {
    getDeviceSources(): Promise<[DeviceSource]> {
        return Promise.resolve(DEVICE_SOURCES); 
    }
}
21
OvSleep

Vous devez ajouter *ngIf directive à votre slick-slider donc il est inséré dans DOM après le remplissage de la source de données, dans ce cas, il s'agit de la variable sources:

<slick-slider *ngIf="sources">
    <div *ngFor="let source of sources">
        <img class="btn btn-lg" (click)="watchSource(source)" src="/assets/img/{{source.name}}.png" />
    </div>
</slick-slider>
12
Stefan Svrkota

Dans mon cas, l'astuce avec * ngIf n'était pas suffisante. J'appelle REST service dans ngOnInit et je reçois une réponse là où dans l'abonnement je définis le tableau. La seule solution possible pour moi était d'ajouter manuellement des éléments slick par la fonction slick 'slickAdd' directement à partir de TypeScript.

jQuery('.my-slick').slick('slickAdd', '<div><h3>ahoj</h3></div>');

Peut-être que cela aidera quelqu'un ...

0
gabriel