Skip to content

Commit f7e23a0

Browse files
authored
Fix Carousel on Async Wrapped Components (#470)
@santoshyadavdev please check method "_checkChanges()". It has the same content of the previous DoCheck but I removed the _defDirectives defined control and added the _markedForCheck flag to recheck _arrayChanges. _checkChanges() is also triggered in AfterContentInit when we are sure _defDirectives are defined.
1 parent 2e9310d commit f7e23a0

20 files changed

+1454
-72
lines changed

apps/ngu-carousel-example/project.json

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"build": {
1717
"executor": "@angular-devkit/build-angular:browser-esbuild",
1818
"options": {
19-
"outputPath": "dist/apps/ngu-carousel-example",
19+
"outputPath": "dist/apps/ngu-carousel-example/browser",
2020
"index": "apps/ngu-carousel-example/src/index.html",
2121
"main": "apps/ngu-carousel-example/src/main.ts",
2222
"polyfills": "apps/ngu-carousel-example/src/polyfills.ts",
@@ -93,7 +93,9 @@
9393
"apps/ngu-carousel-example/src/favicon.ico",
9494
"apps/ngu-carousel-example/src/assets"
9595
],
96-
"styles": ["apps/ngu-carousel-example/src/styles.scss"],
96+
"styles": [
97+
"apps/ngu-carousel-example/src/styles.scss"
98+
],
9799
"scripts": []
98100
}
99101
},
@@ -119,6 +121,61 @@
119121
"outputPath": "dist/apps/ngu-carousel-example",
120122
"reportPath": "reports"
121123
}
124+
},
125+
"server": {
126+
"executor": "@angular-devkit/build-angular:server",
127+
"options": {
128+
"outputPath": "dist/apps/ngu-carousel-example/server",
129+
"main": "apps/ngu-carousel-example/server.ts",
130+
"tsConfig": "apps/ngu-carousel-example/tsconfig.server.json",
131+
"inlineStyleLanguage": "scss"
132+
},
133+
"configurations": {
134+
"production": {
135+
"outputHashing": "media"
136+
},
137+
"development": {
138+
"buildOptimizer": false,
139+
"optimization": false,
140+
"sourceMap": true,
141+
"extractLicenses": false,
142+
"vendorChunk": true
143+
}
144+
},
145+
"defaultConfiguration": "production"
146+
},
147+
"serve-ssr": {
148+
"executor": "@nguniversal/builders:ssr-dev-server",
149+
"configurations": {
150+
"development": {
151+
"browserTarget": "ngu-carousel-example:build:development",
152+
"serverTarget": "ngu-carousel-example:server:development"
153+
},
154+
"production": {
155+
"browserTarget": "ngu-carousel-example:build:production",
156+
"serverTarget": "ngu-carousel-example:server:production"
157+
}
158+
},
159+
"defaultConfiguration": "development"
160+
},
161+
"prerender": {
162+
"executor": "@nguniversal/builders:prerender",
163+
"options": {
164+
"routes": [
165+
"/"
166+
]
167+
},
168+
"configurations": {
169+
"production": {
170+
"browserTarget": "ngu-carousel-example:build:production",
171+
"serverTarget": "ngu-carousel-example:server:production"
172+
},
173+
"development": {
174+
"browserTarget": "ngu-carousel-example:build:development",
175+
"serverTarget": "ngu-carousel-example:server:development"
176+
}
177+
},
178+
"defaultConfiguration": "production"
122179
}
123180
}
124-
}
181+
}

apps/ngu-carousel-example/server.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import 'zone.js/node';
2+
3+
import { APP_BASE_HREF } from '@angular/common';
4+
import { ngExpressEngine } from '@nguniversal/express-engine';
5+
import express from 'express';
6+
import { existsSync } from 'node:fs';
7+
import { join } from 'node:path';
8+
import { AppServerModule } from './src/main.server';
9+
10+
// The Express app is exported so that it can be used by serverless Functions.
11+
export function app(): express.Express {
12+
const server = express();
13+
const distFolder = join(process.cwd(), 'dist/apps/ngu-carousel-example/browser');
14+
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
15+
16+
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/main/modules/express-engine)
17+
server.engine('html', ngExpressEngine({
18+
bootstrap: AppServerModule
19+
}));
20+
21+
server.set('view engine', 'html');
22+
server.set('views', distFolder);
23+
24+
// Example Express Rest API endpoints
25+
// server.get('/api/**', (req, res) => { });
26+
// Serve static files from /browser
27+
server.get('*.*', express.static(distFolder, {
28+
maxAge: '1y'
29+
}));
30+
31+
// All regular routes use the Universal engine
32+
server.get('*', (req, res) => {
33+
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
34+
});
35+
36+
return server;
37+
}
38+
39+
function run(): void {
40+
const port = process.env['PORT'] || 4000;
41+
42+
// Start up the Node server
43+
const server = app();
44+
server.listen(port, () => {
45+
console.log(`Node Express server listening on http://localhost:${port}`);
46+
});
47+
}
48+
49+
// Webpack will replace 'require' with '__webpack_require__'
50+
// '__non_webpack_require__' is a proxy to Node 'require'
51+
// The below code is to ensure that the server is run only when not requiring the bundle.
52+
declare const __non_webpack_require__: NodeRequire;
53+
const mainModule = __non_webpack_require__.main;
54+
const moduleFilename = mainModule && mainModule.filename || '';
55+
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
56+
run();
57+
}
58+
59+
export * from './src/main.server';

apps/ngu-carousel-example/src/app/app-routing.module.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ const routes: Routes = [
1616
loadChildren: () =>
1717
import('./banner-vertical/banner-vertical.module').then(m => m.BannerVerticalModule)
1818
},
19+
{
20+
path: 'wrapped',
21+
loadChildren: () =>
22+
import('./wrapped/wrapped.module').then(m => m.WrappedModule)
23+
},
1924
{
2025
path: 'getting-started',
2126
component: GettingStartedComponent
@@ -28,7 +33,9 @@ const routes: Routes = [
2833
];
2934

3035
@NgModule({
31-
imports: [RouterModule.forRoot(routes)],
36+
imports: [RouterModule.forRoot(routes, {
37+
initialNavigation: 'enabledBlocking'
38+
})],
3239
exports: [RouterModule]
3340
})
3441
export class AppRoutingModule {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { NgModule } from '@angular/core';
2+
import { ServerModule } from '@angular/platform-server';
3+
4+
import { AppModule } from './app.module';
5+
import { AppComponent } from './app.component';
6+
7+
@NgModule({
8+
imports: [
9+
AppModule,
10+
ServerModule,
11+
],
12+
bootstrap: [AppComponent],
13+
})
14+
export class AppServerModule {}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { Component } from '@angular/core';
1+
import { ChangeDetectionStrategy, Component } from '@angular/core';
22

33
@Component({
44
selector: 'app-getting-started',
55
templateUrl: './getting-started.component.html',
6-
styleUrls: ['./getting-started.component.scss']
6+
styleUrls: ['./getting-started.component.scss'],
7+
changeDetection: ChangeDetectionStrategy.OnPush
78
})
89
export class GettingStartedComponent {}

apps/ngu-carousel-example/src/app/main-nav/main-nav.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<a mat-list-item routerLink="/tile">Tile</a>
1313
<a mat-list-item routerLink="/banner">Banner</a>
1414
<a mat-list-item routerLink="/banner-vertical">Banner Vertical</a>
15+
<a mat-list-item routerLink="/wrapped">Wrapped Carousel</a>
1516
</mat-nav-list>
1617
</mat-sidenav>
1718
<mat-sidenav-content>

apps/ngu-carousel-example/src/app/main-nav/main-nav.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
2-
import { Component } from '@angular/core';
2+
import { ChangeDetectionStrategy, Component } from '@angular/core';
33
import { Observable } from 'rxjs';
44
import { map, shareReplay } from 'rxjs/operators';
55

66
@Component({
77
selector: 'app-main-nav',
88
templateUrl: './main-nav.component.html',
9-
styleUrls: ['./main-nav.component.scss']
9+
styleUrls: ['./main-nav.component.scss'],
10+
changeDetection: ChangeDetectionStrategy.OnPush
1011
})
1112
export class MainNavComponent {
1213
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset).pipe(
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<div class="wrapped-carosuel" *ngIf="carouselTileItems.length">
2+
<h2>Wrapped Carousel</h2>
3+
<ngu-carousel #myCarousel [inputs]="config" [dataSource]="carouselTileItems">
4+
<button NguCarouselPrev class="leftRs" [style.opacity]="myCarousel.isFirst ? 0.5 : 1">
5+
&lt;
6+
</button>
7+
8+
<ngu-tile *nguCarouselDef="let item; index as i; let ani = animate" [@slider]="ani">
9+
<ng-container *ngIf="i % 2 === 0">
10+
<ng-container
11+
*ngTemplateOutlet="card; context: { $implicit: item, index: i }"
12+
></ng-container>
13+
</ng-container>
14+
<ng-container *ngIf="i % 2 !== 0">
15+
<div class="tile" [style.background]="'url(' + item + ')'">
16+
<h1>Odd: {{ i + 1 }}</h1>
17+
</div>
18+
</ng-container>
19+
</ngu-tile>
20+
21+
<button NguCarouselNext class="rightRs" [style.opacity]="myCarousel.isLast ? 0.5 : 1">
22+
&gt;
23+
</button>
24+
25+
<ul class="myPoint" NguCarouselPoint>
26+
<li
27+
*ngFor="let i of myCarousel.pointNumbers"
28+
[class.active]="i === myCarousel.activePoint"
29+
(click)="myCarousel.moveTo(i)"
30+
></li>
31+
</ul>
32+
</ngu-carousel>
33+
</div>
34+
35+
<ng-template #card let-item let-i="index">
36+
<div class="tile" [style.background]="'url(' + item + ')'">
37+
<h1>Even: {{ i + 1 }}</h1>
38+
</div>
39+
</ng-template>

0 commit comments

Comments
 (0)