在 ngOnInit 中动态添加的组件或 HTML 元素会添加两次

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

在生命周期中

ngOnInit
我尝试向页面添加一个元素。所以我使用
Renderer2
,创建一个新元素并添加它。问题很简单。该项目被创建两次。请注意,我在
console.log
中有一个
ngOnInit
,并且我在控制台中只收到了一份日志。我必须假设
ngOnInit
并没有真正执行两次。

我尝试在 stackblitz 中重现该问题,但不能...这是代码:https://stackblitz.com/edit/stackblitz-starters-r5psb2?file=src%2Fmain.ts

因此,我尝试使用 IDE(与代码)在空项目中重现该问题,在这种情况下,我遇到了问题。所以我的代码与 stackblitz 中的代码相同,但结果是 2 个

p
元素而不是 1.

请注意,如果我查看页面源代码,我只得到 1 个 p 元素,而在 DOM 中,有 2 个主题。这是页面来源:

<!DOCTYPE html><html lang="en"><head>
  <script type="module" src="/@vite/client"></script>

  <meta charset="utf-8">
  <title>Issue</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.css"></head>
<body><!--nghm-->
  <app-root _nghost-ng-c1098833243="" ng-version="17.3.1" ngh="0" ng-server-context="ssr"><p _ngcontent-ng-c1098833243="">some text</p></app-root>
<script src="polyfills.js" type="module"></script><script src="main.js" type="module"></script>

<script id="ng-state" type="application/json">{"__nghData__":[{}]}</script></body></html>

我认为如果问题没有出现在 stackblitz 中,则它来自我的设置。我尝试禁用 ssr,但它不起作用(即使它起作用,它也很糟糕)。

angular
1个回答
0
投票

这是启用 SSR 和水合作用的预期行为,因为组件的

ngOnInit
在服务器端调用,生成第一个
<p>
,然后在客户端调用,生成第二个
<p>

您可以通过几种方式修复此行为:

  1. 仅在其中一个平台上运行代码
export class MyComponent {
  constructor(@Inject(PLATFORM_ID) private platform: Object) {}

  ngOnInit(): void {
    if (!isPlatformServer(this.platform)) { // <-- runs only on the client
      /* Code for inserting a node */
    }
  }
}
  1. provideClientHydration()
    中删除
    app.config.ts
    ,禁用整个应用程序的水合作用。

  2. 使用

    ngSkipHydration
    属性

    禁用此特定组件的水合作用
@Component({
  /* ... */
  host: { ngSkipHydration: 'true' },
  /* ... */
})

禁用水合作用后,组件仍然运行 ngOnInit 并在服务器上添加一个

<p>
元素,但在客户端,整个 DOM 在应用程序启动之前被擦除

  1. 通过删除
    angular.json
    的architect > build > options部分中的以下行来禁用SSR(禁用预渲染是不够的):
"prerender": true,
"ssr": {
  "entry": "server.ts"
}

在这种情况下,您可能还需要清理一些与 ssr 相关的东西,例如带有

server
后缀的文件。


在做出选择之前,请阅读有关SSRHydration的文档。

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