Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initSlick() #7

Closed
rsmachir opened this issue Aug 30, 2018 · 11 comments
Closed

initSlick() #7

rsmachir opened this issue Aug 30, 2018 · 11 comments

Comments

@rsmachir
Copy link

I have a slide show in the my app.component, the number of slides might change as user navigates through the site, I call initSlick() in ngAfterViewChecked, however it keeps adding to existing slides not re-initializing just with new slides, it keeps appending to what ever is already there, What other technique can we use to re-initialize on route navigation.

@leo6104
Copy link
Owner

leo6104 commented Aug 30, 2018

@rsmachir If you use *ngFor syntax with slides variable like below code (example code in README),

    <ngx-slick-carousel class="carousel" 
                        #slickModal="slick-carousel" 
                        [config]="slideConfig" 
                        (init)="slickInit($event)">
        <div ngxSlickItem *ngFor="let slide of slides" class="slide">
              <img src="{{ slide.img }}" alt="" width="100%">
        </div>
    </ngx-slick-carousel>

You can change the number of slides via append/pop to slides variable. No need to call initSlick() directly.

this.slides.push({ img: '~~~' })

@rsmachir
Copy link
Author

Thank you for your prompt reply. My slides are actually two sets of *ngFor array of objects with data that comes from my API. Seeing your reply, all I had to do was explicitly empty out the array on navigation and let it re-populate from the API. That did the trick.

@leo6104
Copy link
Owner

leo6104 commented Aug 30, 2018

@rsmachir Can you try to assign api's result array directly to slides1/slides2 variable? (without empty array -> re-populate sequence)
My implementation should work without the trick. If not work, i will try to fix it :)

this.router.events.subscribe(ev => {
  this.http.get(~).subscribe(apiResult => { 
     this.slides1 = apiResult[0];
     this.slides2 = apiResult[0];
  });
});
...
        <div ngxSlickItem *ngFor="let slide of slides1" class="slide">
              <img src="{{ slide.img }}" alt="" width="100%">
        </div>
        <div ngxSlickItem *ngFor="let slide of slides2" class="slide">
              <img src="{{ slide.img }}" alt="" width="100%">
        </div>
</div>

@rsmachir
Copy link
Author

rsmachir commented Aug 30, 2018

Which is what I had originally. The challenge I ran into with that is, when I navigate and the API result set changes slide show freezes mid-stream.
This is my code -

<ngx-slick-carousel #slickModal="slick-carousel" [config]="slideConfig">
          <a href="###" target="_blank" ngxSlickItem>
            <div class="slideContainer">

              <table>
                <tr>
                  <td>
                    <img src="/themes/{{UrlInfo$.DBACode.toLowerCase()}}/images/featuredbox_home.png" width="100" alt="Build on Your Lot" />
                  </td>
                  <td>
                    <h6>Build on Your Lot</h6>
                    <div class="caption">We build where you want to live.</div>
                  </td>
                </tr>
              </table>
            </div>
          </a>
          <a (click)="openlenderdisclosure(item.CompanyId)" ngxSlickItem *ngFor="let item of mortcomps$">
            <div class="slideContainer">
              <img src="/themes/{{UrlInfo$.DBACode.toLowerCase()}}/images/{{item.ImageUrl}}" alt="{{item.CompanyName}}" style="margin:auto; padding-top:8px;"
                   title="{{item.CompanyName}}" />
            </div>
          </a>

          <a href="{{promo?.PromoLinkUrl}}" target="_blank" ngxSlickItem *ngFor="let promo of promos$">
            <div class="slideContainer">

              <img [src]="promo.PromoBannerUrl" alt="{{promo.Promotion}}" style="margin:auto; padding-top:8px;" title="{{promo.Promotion}}" />

            </div>
          </a>

        </ngx-slick-carousel>

@leo6104
Copy link
Owner

leo6104 commented Aug 30, 2018

@rsmachir Thanks for reporting the issue. Can you add your ts code part (http request / assign part) for me? After that, i will check it immediately.

(tip) if slick performance is important, please consider to use trackBy syntax in *ngFor.
https://angular.io/api/common/NgForOf
It will minimize ngxSlickItem destroy/create call (minimize slickAdd, slickRemove internal call)

@rsmachir
Copy link
Author

this.mortgagecompanyservice = this.mort.GetMortgageCompanies(this.UrlInfo$.DBACode, this.UrlInfo$.MetroId).subscribe((m: iMortgageCompany[]) => {this.mortcomps$ = m}, error => this.errorMessage = error);

this.tpromo = this.apromo.getPromos(this.UrlInfo$.DBACode, this.UrlInfo$.MetroId, "", "", "", this.promolocation).subscribe((p: iPromotionItem[]) => {this.promos$ = p}, error => this.errorMessage = <any>error);

I will add trackBy and see if that helps with the performance. I'll get back to you, if it does. Thank you.

@leo6104
Copy link
Owner

leo6104 commented Aug 30, 2018

@rsmachir It's weird. It seems work in test code. Did you set your component's change detection strategy as OnPush ? ChangeDetectionStrategy.OnPush

@rsmachir
Copy link
Author

rsmachir commented Aug 30, 2018

No I just used the default. I'm getting much better performance by setting trackBy for *ngFor. Now I ran into another issue, this is a big site, so all my modules are being lazy loaded. On some of my lazy loaded components I have second slide-show on them. On these the main one loaded in the app works fine, but the one lazy loaded one has slight second or two hesitation before auto play kicks in. Any tricks to making the second more smoother - Thank you.
Here is the code on that component.

 <ngx-slick-carousel #slickHLModal="slick-carousel" class="carousel" [config]="HomeListingslideConfig">
    <div ngxSlickItem *ngFor="let photo of photos; trackBy: ResourceTracking" class="slide">

      <img src="{{photo.ResourceURL.toLowerCase()}}" alt="{{ photo.AltText }}" />
      <div class="caption">
        {{photo.AltText}}
      </div>

    </div>
  </ngx-slick-carousel>

@rsmachir
Copy link
Author

rsmachir commented Sep 5, 2018

I can get it to perform better without hesitation if set VariableWidth to false in the configuration. But that leaves wide swaths of white space between the slides. Anything I'm missing in my config.

HomeListingslideConfig = {
							"slidesToShow": 1, "slidesToScroll": 1, "autoplay": true, "autoplay-speed": 4000, "dots": true, "infinite": true, "centerMode": true, "variableWidth": true,
							"arrows": true,
							"prevArrow": "<button type='button' class='slick-prev pull-left'><span class='fa fa-chevron-left'></span></button>",
							"nextArrow": "<button type='button' class='slick-next pull-right'><span class='fa fa-chevron-right'></span></button>",
							"responsive": [
											{
															"breakpoint": 700,
															"settings": {
																			"dots": false,
																			"arrows": false,
																			"centerMode": false,
																			"variableWidth": false,
																			"slidesToShow": 1
															}
											}
							]
			};

@leo6104
Copy link
Owner

leo6104 commented Sep 15, 2018

@rsmachir Sorry for late comment. I found that if initialize slick in ngAfterViewChecked, angular changeDetector wait for rendering slick until next ngAfterViewChecked call.

I fix the cause with 9e0031c - add ngAfterViewInit call for initializing slick. I can't certain it will resolve your issue. Can you check the problem with ngx-slick-carousel 0.4.1 ?

@rsmachir
Copy link
Author

Thank you. That update helped. Getting a much stable performance from it now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants