我正在使用一个Angular 9 SSR应用程序,我试图动态更新每个页面的元标签。
这是一个网站。https:/gameswebapp-stage.herokuapp.com。
每一页,除了 游戏 我能够更新元数据。
例如,挖掘机页面元数据没有变化----。https:/gameswebapp-stage.herokuapp.comgamedigger。
关于 GameComponent
我正在做以下工作。
在 NgOnInit
我叫:(我已经硬编码了。digger
游戏,使其更简单,但它仍然不工作)
ngOnInit(): void {
const gameName = 'digger';
this.gameInfo = dic.GAMES_INFO[gameName];
console.log(`gameInfo`, this.gameInfo);
this.generalService.updateState(dic.STATES.game, this.gameInfo);
}
在 generalService
我正在这样做(请注意,所有的页面都会调用这段代码,而且对他们来说,这段代码确实是有效的。
updateState(state: string, options: any) {
this.state = state;
// notify all subscribes that page is changed
this.stateSource.next(state);
this.updateMetaData(state, options);
if (isPlatformBrowser(this.platformId)) {
// auto scroll to top of page
setTimeout(() => {
const gameTitle = document.getElementById('headerContainer');
if (gameTitle) {
gameTitle.scrollIntoView({behavior: 'smooth'});
}
}, 300);
}
}
updateMetaData(state, options) {
const metaDataInfo = {
title: `${dic.CONSTANTS.appTitle} - `,
description: dic.CONSTANTS.metaData.desc,
keywords: dic.CONSTANTS.metaData.keywords,
// Facebook
url: `${dic.CONSTANTS.appUrL}${state}`,
image: `${dic.CONSTANTS.appUrL}assets/images/`
};
if (options && state === dic.STATES.game) {
metaDataInfo.title += options.name;
metaDataInfo.url += `/${options.fileName}`;
metaDataInfo.image += `${options.fileName}.png`;
metaDataInfo.description = options.desc;
metaDataInfo.keywords += `,${options.name}`;
}
else {
metaDataInfo.title += state;
metaDataInfo.image += `logo.png`;
}
console.log('metaDataInfo', metaDataInfo);
this.titleService.setTitle(metaDataInfo.title);
this.metaTagService.updateTag({ name: 'description', content: metaDataInfo.description });
this.metaTagService.updateTag({ name: 'keywords', content: metaDataInfo.keywords });
// Facebook
this.metaTagService.updateTag({ property: 'og:title', content: metaDataInfo.title });
this.metaTagService.updateTag({ property: 'og:url', content: metaDataInfo.url });
this.metaTagService.updateTag({ property: 'og:description', content: metaDataInfo.description });
this.metaTagService.updateTag({ property: 'og:image', content: metaDataInfo.image });
}
但不幸的是,index.html中的meta标签并没有做到 不 改变在游戏(对于所有其他页面它确实改变)。
这是我的 server.ts
编码
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
const domino = require('domino');
const fs = require('fs');
const template = fs.readFileSync('dist/games/browser/index.html').toString();
const win = domino.createWindow(template);
global['window'] = win;
global['document'] = win.document;
global['DOMTokenList'] = win.DOMTokenList;
global['Node'] = win.Node;
global['Text'] = win.Text;
global['HTMLElement'] = win.HTMLElement;
global['navigator'] = win.navigator;
// global['localStorage'] = win.localStorage;
import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';
import * as compression from 'compression';
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() {
const server = express();
const distFolder = join(process.cwd(), 'dist/games/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.use(compression());
server.disable('x-powered-by');
server.set('view engine', 'html');
server.set('views', distFolder);
// 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() {
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';
我得到一个错误在 server.ts
文件(其他页面一切正常,元数据也有显示)。
这个错误实际上似乎发生在2种情况下。
按Ctrl + U(非常奇怪)
如果我刷新页面
这就是错误。
url: /game/digger
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'ɵcmp' of undefined
TypeError: Cannot read property 'ɵcmp' of undefined
at getComponentDef (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2078832)
at extractDirectiveDef (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2077372)
at Array.map (<anonymous>)
at def.directiveDefs (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2076998)
at createTView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2136884)
at getOrCreateTComponentView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2135760)
at createRootComponentView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2263977)
at ComponentFactory$1.create (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2333950)
at R3ViewContainerRef.createComponent (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2167016)
at router_RouterOutlet.activateWith (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:3550373)
at resolvePromise (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:1926319)
at resolvePromise (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:1925296)
at C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:1928123
at ZoneDelegate.invokeTask (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:1917423)
at Object.onInvokeTask (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2412917)
at ZoneDelegate.invokeTask (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:1917313)
at Zone.runTask (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:1909988)
at drainMicroTaskQueue (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:1921031)
at ZoneTask.invokeTask (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:1919072)
at Server.ZoneTask.options.useG.invoke (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:1918837) {
rejection: TypeError: Cannot read property 'ɵcmp' of undefined
at getComponentDef (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2078832)
at extractDirectiveDef (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2077372)
at Array.map (<anonymous>)
at def.directiveDefs (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2076998)
at createTView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2136884)
at getOrCreateTComponentView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2135760)
at createRootComponentView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2263977)
at ComponentFactory$1.create (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2333950)
at R3ViewContainerRef.createComponent (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2167016)
at router_RouterOutlet.activateWith (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:3550373),
promise: ZoneAwarePromise [Promise] {
__zone_symbol__state: 0,
__zone_symbol__value: TypeError: Cannot read property 'ɵcmp' of undefined
at getComponentDef (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2078832)
at extractDirectiveDef (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2077372)
at Array.map (<anonymous>)
at def.directiveDefs (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2076998)
at createTView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2136884)
at getOrCreateTComponentView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2135760)
at createRootComponentView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2263977)
at ComponentFactory$1.create (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2333950)
at R3ViewContainerRef.createComponent (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2167016)
at router_RouterOutlet.activateWith (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:3550373)
},
zone: Zone {
_parent: Zone {
_parent: null,
_name: '<root>',
_properties: {},
_zoneDelegate: [ZoneDelegate]
},
_name: 'angular',
_properties: { isAngularZone: true, maybeDelayChangeDetection: false },
_zoneDelegate: ZoneDelegate {
_taskCounts: [Object],
zone: [Circular],
_parentDelegate: [ZoneDelegate],
_forkZS: null,
_forkDlgt: null,
_forkCurrZone: null,
_interceptZS: null,
_interceptDlgt: null,
_interceptCurrZone: null,
_invokeZS: [Object],
_invokeDlgt: [ZoneDelegate],
_invokeCurrZone: [Circular],
_handleErrorZS: [Object],
_handleErrorDlgt: [ZoneDelegate],
_handleErrorCurrZone: [Circular],
_scheduleTaskZS: [Object],
_scheduleTaskDlgt: [ZoneDelegate],
_scheduleTaskCurrZone: [Circular],
_invokeTaskZS: [Object],
_invokeTaskDlgt: [ZoneDelegate],
_invokeTaskCurrZone: [Circular],
_cancelTaskZS: [Object],
_cancelTaskDlgt: [ZoneDelegate],
_cancelTaskCurrZone: [Circular],
_hasTaskZS: [Object],
_hasTaskDlgt: [ZoneDelegate],
_hasTaskDlgtOwner: [Circular],
_hasTaskCurrZone: [Circular]
}
},
task: ZoneTask {
_zone: Zone {
_parent: [Zone],
_name: 'angular',
_properties: [Object],
_zoneDelegate: [ZoneDelegate]
},
runCount: 0,
_zoneDelegates: null,
_state: 'notScheduled',
type: 'microTask',
source: 'Promise.then',
data: ZoneAwarePromise [Promise] {
__zone_symbol__state: 0,
__zone_symbol__value: TypeError: Cannot read property 'ɵcmp' of undefined
at getComponentDef (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2078832)
at extractDirectiveDef (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2077372)
at Array.map (<anonymous>)
at def.directiveDefs (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2076998)
at createTView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2136884)
at getOrCreateTComponentView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2135760)
at createRootComponentView (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2263977)
at ComponentFactory$1.create (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2333950)
at R3ViewContainerRef.createComponent (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:2167016)
at router_RouterOutlet.activateWith (C:\Users\Yoni\WebstormProjects\games\dist\games\server\main.js:1:3550373)
},
scheduleFn: undefined,
cancelFn: undefined,
callback: [Function],
invoke: [Function]
}
我的模块ngx-bar-rating出现了问题。