Skip to content

Commit

Permalink
Fix Carousel on Async Wrapped Components (#470)
Browse files Browse the repository at this point in the history
@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.
  • Loading branch information
luca-peruzzo authored Jul 19, 2023
1 parent 2e9310d commit f7e23a0
Show file tree
Hide file tree
Showing 20 changed files with 1,454 additions and 72 deletions.
63 changes: 60 additions & 3 deletions apps/ngu-carousel-example/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"build": {
"executor": "@angular-devkit/build-angular:browser-esbuild",
"options": {
"outputPath": "dist/apps/ngu-carousel-example",
"outputPath": "dist/apps/ngu-carousel-example/browser",
"index": "apps/ngu-carousel-example/src/index.html",
"main": "apps/ngu-carousel-example/src/main.ts",
"polyfills": "apps/ngu-carousel-example/src/polyfills.ts",
Expand Down Expand Up @@ -93,7 +93,9 @@
"apps/ngu-carousel-example/src/favicon.ico",
"apps/ngu-carousel-example/src/assets"
],
"styles": ["apps/ngu-carousel-example/src/styles.scss"],
"styles": [
"apps/ngu-carousel-example/src/styles.scss"
],
"scripts": []
}
},
Expand All @@ -119,6 +121,61 @@
"outputPath": "dist/apps/ngu-carousel-example",
"reportPath": "reports"
}
},
"server": {
"executor": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/apps/ngu-carousel-example/server",
"main": "apps/ngu-carousel-example/server.ts",
"tsConfig": "apps/ngu-carousel-example/tsconfig.server.json",
"inlineStyleLanguage": "scss"
},
"configurations": {
"production": {
"outputHashing": "media"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"sourceMap": true,
"extractLicenses": false,
"vendorChunk": true
}
},
"defaultConfiguration": "production"
},
"serve-ssr": {
"executor": "@nguniversal/builders:ssr-dev-server",
"configurations": {
"development": {
"browserTarget": "ngu-carousel-example:build:development",
"serverTarget": "ngu-carousel-example:server:development"
},
"production": {
"browserTarget": "ngu-carousel-example:build:production",
"serverTarget": "ngu-carousel-example:server:production"
}
},
"defaultConfiguration": "development"
},
"prerender": {
"executor": "@nguniversal/builders:prerender",
"options": {
"routes": [
"/"
]
},
"configurations": {
"production": {
"browserTarget": "ngu-carousel-example:build:production",
"serverTarget": "ngu-carousel-example:server:production"
},
"development": {
"browserTarget": "ngu-carousel-example:build:development",
"serverTarget": "ngu-carousel-example:server:development"
}
},
"defaultConfiguration": "production"
}
}
}
}
59 changes: 59 additions & 0 deletions apps/ngu-carousel-example/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'zone.js/node';

import { APP_BASE_HREF } from '@angular/common';
import { ngExpressEngine } from '@nguniversal/express-engine';
import express from 'express';
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import { AppServerModule } from './src/main.server';

// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/apps/ngu-carousel-example/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/main/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule
}));

server.set('view engine', 'html');
server.set('views', distFolder);

// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));

// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});

return server;
}

function run(): void {
const port = process.env['PORT'] || 4000;

// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}

// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}

export * from './src/main.server';
9 changes: 8 additions & 1 deletion apps/ngu-carousel-example/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const routes: Routes = [
loadChildren: () =>
import('./banner-vertical/banner-vertical.module').then(m => m.BannerVerticalModule)
},
{
path: 'wrapped',
loadChildren: () =>
import('./wrapped/wrapped.module').then(m => m.WrappedModule)
},
{
path: 'getting-started',
component: GettingStartedComponent
Expand All @@ -28,7 +33,9 @@ const routes: Routes = [
];

@NgModule({
imports: [RouterModule.forRoot(routes)],
imports: [RouterModule.forRoot(routes, {
initialNavigation: 'enabledBlocking'
})],
exports: [RouterModule]
})
export class AppRoutingModule {}
14 changes: 14 additions & 0 deletions apps/ngu-carousel-example/src/app/app.server.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
imports: [
AppModule,
ServerModule,
],
bootstrap: [AppComponent],
})
export class AppServerModule {}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';

@Component({
selector: 'app-getting-started',
templateUrl: './getting-started.component.html',
styleUrls: ['./getting-started.component.scss']
styleUrls: ['./getting-started.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class GettingStartedComponent {}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<a mat-list-item routerLink="/tile">Tile</a>
<a mat-list-item routerLink="/banner">Banner</a>
<a mat-list-item routerLink="/banner-vertical">Banner Vertical</a>
<a mat-list-item routerLink="/wrapped">Wrapped Carousel</a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { Observable } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';

@Component({
selector: 'app-main-nav',
templateUrl: './main-nav.component.html',
styleUrls: ['./main-nav.component.scss']
styleUrls: ['./main-nav.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MainNavComponent {
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset).pipe(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<div class="wrapped-carosuel" *ngIf="carouselTileItems.length">
<h2>Wrapped Carousel</h2>
<ngu-carousel #myCarousel [inputs]="config" [dataSource]="carouselTileItems">
<button NguCarouselPrev class="leftRs" [style.opacity]="myCarousel.isFirst ? 0.5 : 1">
&lt;
</button>

<ngu-tile *nguCarouselDef="let item; index as i; let ani = animate" [@slider]="ani">
<ng-container *ngIf="i % 2 === 0">
<ng-container
*ngTemplateOutlet="card; context: { $implicit: item, index: i }"
></ng-container>
</ng-container>
<ng-container *ngIf="i % 2 !== 0">
<div class="tile" [style.background]="'url(' + item + ')'">
<h1>Odd: {{ i + 1 }}</h1>
</div>
</ng-container>
</ngu-tile>

<button NguCarouselNext class="rightRs" [style.opacity]="myCarousel.isLast ? 0.5 : 1">
&gt;
</button>

<ul class="myPoint" NguCarouselPoint>
<li
*ngFor="let i of myCarousel.pointNumbers"
[class.active]="i === myCarousel.activePoint"
(click)="myCarousel.moveTo(i)"
></li>
</ul>
</ngu-carousel>
</div>

<ng-template #card let-item let-i="index">
<div class="tile" [style.background]="'url(' + item + ')'">
<h1>Even: {{ i + 1 }}</h1>
</div>
</ng-template>
Loading

0 comments on commit f7e23a0

Please sign in to comment.