Angular 9 SSR - 无法动态更改元标签。

问题描述 投票:1回答:1

我正在使用一个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种情况下。

  1. 按Ctrl + U(非常奇怪)

  2. 如果我刷新页面

这就是错误。

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]
  }
angular server-side-rendering angular-universal
1个回答
0
投票

我的模块ngx-bar-rating出现了问题。

© www.soinside.com 2019 - 2024. All rights reserved.