繁体   English   中英

Angular SSR:不渲染纯 html 页面

[英]Angular SSR: not rendering pure html page

我们正在开发一个 angularJs 项目,我们的主页包含我们调用一些 API 并相应地填充数据的代码。 我们需要服务器端渲染,所以我们按照本教程进行操作。 我们运行了npm run dev:ssr一切正常,但是我们没有得到完全生成的纯 html/css 页面。 我可以看到页面尚未呈现服务器端。 它仍在浏览器端呈现。 我不知道我在这里做错了什么。 任何帮助将不胜感激。

Nodejs 版本:14.17.2 操作系统:ubuntu 20。

这是我的 package.json 文件:-

 { "name": "piping-mart-client", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", "dev:ssr": "ng run pipingMartClient:serve-ssr", "serve:ssr": "node dist/pipingMartClient/server/main.js", "build:ssr": "ng build && ng run pipingMartClient:server", "prerender": "ng run pipingMartClient:prerender" }, "private": true, "dependencies": { "@angular/animations": "~13.1.0", "@angular/common": "~13.1.0", "@angular/compiler": "~13.1.0", "@angular/core": "~13.1.0", "@angular/forms": "~13.1.0", "@angular/localize": "~13.1.0", "@angular/platform-browser": "~13.1.0", "@angular/platform-browser-dynamic": "~13.1.0", "@angular/platform-server": "~13.1.0", "@angular/router": "~13.1.0", "@ng-bootstrap/ng-bootstrap": "^12.0.0", "@ng-select/ng-select": "^8.1.1", "@nguniversal/express-engine": "^13.0.2", "@popperjs/core": "^2.10.2", "angular-material": "^1.2.5", "angular-ng-autocomplete": "^2.0.8", "angular-responsive-carousel": "^2.1.2", "bootstrap": "^5.1.3", "countrycitystatejson": "^20.8.14", "ejs": "^3.1.6", "express": "^4.15.2", "font-awesome": "^4.7.0", "intl-tel-input": "^17.0.16", "jquery": "^3.6.0", "localstorage-polyfill": "^1.0.1", "ng2-tel-input": "^2.3.0", "ngx-owl-carousel-o": "^7.0.2", "ngx-select-dropdown": "^2.1.0", "ngx-slick-carousel": "^0.6.0", "path": "^0.12.7", "rxjs": "~7.4.0", "sessionstorage": "^0.1.0", "slick-carousel": "^1.8.1", "sweetalert2": "^11.4.9", "tslib": "^2.3.0", "zone.js": "~0.11.4" }, "devDependencies": { "@angular-devkit/build-angular": "^13.2.6", "@angular/cli": "~13.1.2", "@angular/compiler-cli": "~13.1.0", "@nguniversal/builders": "^13.0.2", "@types/express": "^4.17.0", "@types/jasmine": "~3.10.0", "@types/node": "^12.11.1", "jasmine-core": "~3.10.0", "karma": "~6.3.0", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.1.0", "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "~1.7.0", "typescript": "~4.5.2" } }

我的 productcomponent.html 页面(这是我们期望呈现的页面。这是加载应用程序时加载的第一页)。

 <div id="content"> <div class="container"> <div class="row"> <div class="col-md-3 col-sm-6 col-sm-12"> <div class="pro-circle p-4"> <img src="{{this.product?.logo || 'https://www.example.com/images/logo.png'}}" class="img-responsive lazyload" alt="Pipes" title="Pipes" /> <h1 class="tab-title">{{this.product.name}}</h1> </div> </div> <div class="col-md-9 col-sm-6 col-sm-12" id="description"> <div id="ProdDesc" class="text show-more-height" [innerHTML]="this.product['description']" > </div> <div class="show-more"><button class="btn more">Show More</button></div> <div class="clearfix"></div> <div class="container mt-5"> <div class="slide-box mt-5" *ngFor="let slide of material; let i = index;"> <div class="recent-projects"> <a (click)="goToSupplierOfMaterial(slide)" > <h4 class="title"> <span >{{slide.name}} </span></h4></a> <div class="projects-carousel touch-carousel"> <owl-carousel-o [options]="customOptions"> <ng-container *ngFor="let gradeList of slide.gradeDetail"> <ng-template carouselSlide [id]="gradeList.gradeId"> <img [src]="gradeList.logo" [alt]="gradeList.alt" [title]="gradeList.name" style="height: 20vh;"> <div class="portfolio-details text-center"> <a class="text-underline cursor-pointer" > <h4 (click)="goToSupplier(gradeList)">{{gradeList.name}}</h4> </a> </div> </ng-template> </ng-container> </owl-carousel-o> </div> </div> </div> </div> </div> </div> </div>

我的 product.component.ts 页面:-

 import { HttpClient } from '@angular/common/http'; import { Component, OnInit, PLATFORM_ID, Inject} from '@angular/core'; import { ActivatedRoute, Router} from '@angular/router'; import { OwlOptions } from 'ngx-owl-carousel-o'; import { CookieService } from 'src/app/shared/service/cookie.service'; import { DataService } from 'src/app/shared/service/DataService'; import * as $ from "jquery"; import { isPlatformBrowser, isPlatformServer} from '@angular/common' @Component({ selector: 'app-product', templateUrl: './product.component.html', styleUrls: ['./product.component.scss'] }) export class ProductComponent implements OnInit { htmlPage: any; name: any; selectedProduct: any []; arrayOfValues: Array<string>; productCategory: any; product: any; material: any; materialArray = []; customOptions: OwlOptions = { loop: false, mouseDrag: true, autoplay: true, touchDrag: false, pullDrag: false, dots: false, margin: 10, navSpeed: 700, navText: ['<i class="fa-solid fa-chevron-left"></i>', '<i class="fa fa-angle-right" aria-hidden="true"></i>'], responsive: { 0: { items: 1 }, 400: { items: 4 }, 740: { items: 4 }, 940: { items: 4 } }, nav: true } description: string; constructor(private activatedRoute: ActivatedRoute, private router: Router, private _dataService: DataService, private http: HttpClient, private cookieService: CookieService, @Inject(PLATFORM_ID) private _platformId: Object) { } ngOnInit(){ if (isPlatformBrowser(this._platformId)) { this.activatedRoute.params.subscribe(params => { this.name = params['name']; }); this.product = JSON.parse(localStorage.getItem("selectedProduct")); this.fetchMaterial(this.product['productId']) } $(".show-more").click(function () { if($(".text").hasClass("show-more-height")) { $(this).text("Show Less..."); } else { $(this).text("Show More..."); } $(".text").toggleClass("show-more-height"); }); } public fetchMaterial(productId){ this.http.post('http://pipe.example.com/product/materials',{"productId": productId, "includeGrades": true }).subscribe( (res: any) => { this.material = res.data; }, error => { console.log(JSON.stringify(error.json())); } ) } public fetchProduct() { this.http.post('http://pipe.example.com/product/products',{"name": this.name }).subscribe( (res: any) => { //this.productCategory = res.data; //console.log(res.data); this.selectedProduct = res.data; }, error => { console.log(JSON.stringify(error.json())); } ) } public goToSupplier(grade) { console.log(grade); this.router.navigate(['/product/detail/'+ grade.name]); localStorage.setItem("selectedGrade", JSON.stringify(grade)); } public goToSupplierOfMaterial(material) { console.log(material); this.router.navigate(['/material/'+ material.name]); localStorage.setItem("selectedMaterial", JSON.stringify(material)); } }

我的 server.ts 文件(运行 ng add @nguniversal/express-engine 后生成)

 import 'zone.js/dist/zone-node'; import { ngExpressEngine } from '@nguniversal/express-engine'; import * as express from 'express'; import { join } from 'path'; import { AppServerModule } from './src/main.server'; import { APP_BASE_HREF } from '@angular/common'; import { existsSync } from 'fs'; // 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/pipingMartClient/browser'); const indexHtml = existsSync(join(distFolder, 'index.original.html'))? 'index.original.html': 'index'; // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/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';

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM