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

nz-carousel breaks SSR (Angular universal) #4292

Closed
timadevelop opened this issue Oct 14, 2019 · 6 comments · Fixed by #5671
Closed

nz-carousel breaks SSR (Angular universal) #4292

timadevelop opened this issue Oct 14, 2019 · 6 comments · Fixed by #5671

Comments

@timadevelop
Copy link

timadevelop commented Oct 14, 2019

Reproduction link

https://github.com/timadevelop/saasWebClient/tree/master/src/app/modules/shared/carousel

Steps to reproduce

  • Setup angular universal with preboot
  • Use nz-carousel component
  • Open browser & load page
  • Browser loads and shows HTML from SSR, Angular client-side script bootstraps application but doesn't attach it to the rendered DOM.

What is expected?

A preview instance of nz-carousel from the server-side and a working one after the application was bootstrapped in the browser. Normal angular application bootstrap process and events (like click) handling.

What is actually happening?

I see a vertical list of images, carousel dots and some error that is not logged into console both on a server- and client-side (Angular client-side script is not handling events after app is bootstrapped).

When I remove nz-carousel from my component template it works like a charm (client accepts html from the server, bootstraps application and handles all events (like click/swap/mouseover)).

Environment Info
ng-zorro-antd 8.3.1
Browser Chrome 77.0

I found this comment, it says:
... some of the components like nz-carousel is not supporting Angular Universal.. Is it true and could we fix it?

There are a lot of projects for angular universal carousel implementation. Like this one: ngu-carousel, but all of them are not maintained at all and have a lot of problems.

P.s. Here is my app initializer for preboot and flickering removal timadevelop/saasWebClient/src/app/app.module.ts

@timadevelop
Copy link
Author

I tried to do something like this: timadevelop/servicescope-web-client@25ce34f (hide nz-carousel on server-side and show it in browser), but realized that this approach requires re-rendering the whole DOM after browser accepts html from the server-side which removes all the work made by preboot.

@timadevelop
Copy link
Author

I discovered that after app bootstrapping on client-side with nz-carousel there are 2 <app-root> elements in HTML:

  1. The first one is from the server-side and has ng-non-bindable attribute (added on client-side js runtime).
  2. The second one is the working one bootstrapped on client-side, but has style="display: none;"

This happens when I try to hide nz-carousel on the server-side and show it in a browser, which makes sense for me because DOM trees are different.

But the same happens when I use nz-carousel both on client-size and server-size.

On app-root from client-side (bootstrapped during client-side runtime and hidden one) nz-carousels slick-list looks like this:

<div class="slick-list" tabindex="-1" style="height: 0px;">
    <div class="slick-track"
        style="height: 0px; width: 0px; transform: translate3d(0px, 0px, 0px);">
        <!---->
        <div _ngcontent-saaswebclient-c13="" class="carousel-content slick-slide ng-star-inserted"
            nz-carousel-content="" style="position: relative; width: 0px; height: 0px;">
            <div _ngcontent-saaswebclient-c13=""
                class="image ant-row-flex ant-row-flex-middle ant-row-flex-center" nz-row=""
                nzalign="middle" nzjustify="center" nztype="flex"><img
                    _ngcontent-saaswebclient-c13=""
                    src="http://api:9123/saas_api/media/images/2019/07/09/back_w222_chin.jpg"></div>
        </div>
        <div _ngcontent-saaswebclient-c13=""
            class="carousel-content slick-slide ng-star-inserted slick-active"
            nz-carousel-content="" style="position: relative; width: 0px; height: 0px;">
            <div _ngcontent-saaswebclient-c13=""
                class="image ant-row-flex ant-row-flex-middle ant-row-flex-center" nz-row=""
                nzalign="middle" nzjustify="center" nztype="flex"><img
                    _ngcontent-saaswebclient-c13=""
                    src="http://api:9123/saas_api/media/images/2019/07/09/Selection_020.jpg"></div>
        </div>
    </div>
</div>

On app-root from server-side (visible one, with ng-non-bindable attribute added in browser):

<div class="slick-list" tabindex="-1">
    <div class="slick-track">
        <!---->
        <div _ngcontent-sc15="" class="carousel-content slick-slide slick-active ng-star-inserted"
            nz-carousel-content="">
            <div _ngcontent-sc15="" class="image ant-row-flex ant-row-flex-middle ant-row-flex-center" nz-row=""
                nzalign="middle" nzjustify="center" nztype="flex"><img _ngcontent-sc15=""
                    src="http://api:9123/saas_api/media/images/2019/07/09/back_w222_chin.jpg"></div>
        </div>
        <div _ngcontent-sc15="" class="carousel-content slick-slide ng-star-inserted" nz-carousel-content="">
            <div _ngcontent-sc15="" class="image ant-row-flex ant-row-flex-middle ant-row-flex-center" nz-row=""
                nzalign="middle" nzjustify="center" nztype="flex"><img _ngcontent-sc15=""
                    src="http://api:9123/saas_api/media/images/2019/07/09/Selection_020.jpg"></div>
        </div>
    </div>
</div>

timadevelop added a commit to timadevelop/servicescope-web-client that referenced this issue Oct 15, 2019
@timadevelop
Copy link
Author

I ended up creating a simple carousel component.

Maybe this could help you:
I use viewport percents

{
      width: (items?.length * 100) + '%',
      left: (-activeIndex * 100) + '%'
}

instead of getBoundingClientRect and unitWidth in pixels you use here:

const rect = carousel.el.getBoundingClientRect();

and here:
this.renderer.setStyle(this.slickTrackEl, 'transform', `translate3d(${-activeIndex * this.unitWidth}px, 0, 0)`);

@wzhudev
Copy link
Member

wzhudev commented Oct 15, 2019

I ended up creating a simple carousel component.

Maybe this could help you:
I use viewport percents

{
      width: (items?.length * 100) + '%',
      left: (-activeIndex * 100) + '%'
}

instead of getBoundingClientRect and unitWidth in pixels you use here:

const rect = carousel.el.getBoundingClientRect();

and here:

this.renderer.setStyle(this.slickTrackEl, 'transform', `translate3d(${-activeIndex * this.unitWidth}px, 0, 0)`);

Hi. Thank you for looking into this. But I am afraid this solution is not suitable for situations when carousel is not full-page wide. We have to use getBoundingClientRect in those cases.

@timadevelop
Copy link
Author

@wendzhue I use a full-page wide carousel only on mobile devices. Here's the screenshot from a desktop device of my app where I use percentages for carousel:

image

I deployed the SSR application on my local server. You could try the carousel on the following page: https://demo.brainhub.co/saas_web/seeks/6.

Not sure about the number of people using both nz-carousel and SSR, but I believe this problem is pretty important because carousels are used by a lot of websites.

Anyway, I'm totally satisfied now, this issue is not urgent for me.

Hope this helps. If there's something I could help with just mention me and I'll answer as soon as I can 👐

@vthinkxie vthinkxie mentioned this issue Aug 13, 2020
48 tasks
wzhudev pushed a commit to wzhudev/ng-zorro-antd that referenced this issue Aug 13, 2020
@wzhudev
Copy link
Member

wzhudev commented Aug 13, 2020

@timadevelop Hi! Sorry for my late reply.

I support SSR for the carousel component in #5671. For SSR, only the first carousel would be rendered and it would take 100% width of the carousel component. Let me know what you think about this. Cheers! 🥂

wzhudev pushed a commit to wzhudev/ng-zorro-antd that referenced this issue Sep 13, 2020
wenqi73 pushed a commit to wzhudev/ng-zorro-antd that referenced this issue Sep 14, 2020
wenqi73 pushed a commit to wzhudev/ng-zorro-antd that referenced this issue Sep 14, 2020
hsuanxyz pushed a commit that referenced this issue Sep 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants