首页 > 其他分享 >关于 Angular Universal 应用渲染两次的问题

关于 Angular Universal 应用渲染两次的问题

时间:2023-11-17 20:44:49浏览次数:34  
标签:AppModule err 启动 Universal 渲染 应用 Angular 加载

Angular Repository url:https://github.com/angular/angular-cli/issues/7477

现象:

I built a sample repo using angular-cli and followed the steps in the Universal Rendering story to enable server side rendering. The application loads well on running, but I see the client rendering also happening after the page is served from the server. So the page gets rendered from the server and then the content disappears for a second as the client rendering happens.

观察到 page 从服务器端 serve 之后,client side rendering 还会再次发生。有一瞬间的功夫,服务器端渲染的内容消失了,client rendering 接着发生。

有网友回复:

The server renders the page without any state and outputs static HTML to view in the browser while the angular application is being bootstrapped. A re-render when the application has been bootstrapped is required to use state saved in the browser such as logged in user information.

SSR 渲染出的是纯粹的 Static HTML,没有任何状态,也无法响应用户的交互。

当应用在客户端完成 Boostrap 之后,re-render 是必要的,以便使用服务器端静态 HTML 里嵌入的通过 State Transfer 传递的业务数据(这些业务数据在 SSR 时通过服务器端执行的 AJAX,从 API server 读取)。

The initial page contains static HTML which needs to be replaced with your angular application once bootstrapped.

这些静态页面的内容,需要被 Angular 应用在客户端 Bootstrap 之后重新渲染的内容所替换。

To make the transfer state work, the Angular application must be bootstrapped after the DOM is loaded. This is because, the data transferred from the server is stored in an HTML element and this element should be accessible to Angular to get the data. Open the file main.ts and move the application bootstrap logic inside the DOMContentLoaded event as shown below:

因为 Transfer State 的工作机制是解析嵌入在 HTML 页面里的 DOM 元素,所以客户端渲染的 Angular 应用,需要等待 DOM 加载之后再进行 Bootstrap.

为此我们需要在 main.ts 文件里编写下面的代码:

document.addEventListener('DOMContentLoaded', () => {  
  platformBrowserDynamic().bootstrapModule(AppModule)    
  .catch(err => console.log(err));
});

这段代码是Angular应用的入口点,它有以下作用:

  1. 等待文档加载完成document.addEventListener('DOMContentLoaded', ...) 表示在文档(DOM)加载完成后执行特定的操作。这是为了确保JavaScript代码在HTML文档完全加载后运行,以避免在DOM元素还未准备好的情况下执行操作,从而避免潜在的错误。

  2. 动态启动Angular应用platformBrowserDynamic().bootstrapModule(AppModule) 是Angular的核心方法之一,它用于动态启动(bootstrap)一个Angular应用。在这里,它将 AppModule 作为应用的根模块来启动。

  3. 处理启动失败.catch(err => console.log(err)) 表示在启动过程中如果出现错误,将错误信息打印到控制台。这是为了帮助开发人员调试应用并捕获潜在的问题。

让我们详细解释每个部分,并举例说明其作用:

1. 等待文档加载完成 (document.addEventListener('DOMContentLoaded', ...))

这是为了确保在HTML文档完全加载后再执行Angular应用的启动过程。当浏览器加载HTML页面时,它按照从上到下的顺序逐步构建DOM树。如果你的JavaScript代码在DOM还没有完全加载之前执行,那么它可能无法找到所需的DOM元素,导致错误或不稳定的行为。

例如,假设你的Angular应用需要在特定的HTML元素上渲染内容,如果你在DOM未加载完成时尝试访问这些元素,可能会出现问题。通过等待DOMContentLoaded 事件,你可以确保DOM已准备就绪,然后再执行Angular应用的启动。

document.addEventListener('DOMContentLoaded', () => {
  // 在这里启动Angular应用
});

2. 动态启动Angular应用 (platformBrowserDynamic().bootstrapModule(AppModule))

这部分代码是启动Angular应用的核心。它使用了Angular的 platformBrowserDynamic 类的实例来动态启动一个Angular应用,然后将 AppModule 作为应用的根模块。这意味着你的Angular应用将从 AppModule 开始加载,并构建整个应用。

让我们来看一个示例,假设有一个名为 AppModule 的Angular模块,它定义了应用的根组件和其他相关配置。这是一个典型的Angular模块定义:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

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

@NgModule({
  imports: [BrowserModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }

在这个示例中,AppModule 使用 @NgModule 装饰器来定义模块,它引入了 BrowserModule 作为依赖,声明了根组件 AppComponent,并将 AppComponent 标记为启动组件(bootstrap 属性)。这意味着 AppComponent 将成为应用的根组件。

在主要的 main.ts 文件中,我们使用 platformBrowserDynamic().bootstrapModule(AppModule) 来启动应用,这将启动整个应用并将 AppComponent 渲染到页面上。

document.addEventListener('DOMContentLoaded', () => {
  platformBrowserDynamic().bootstrapModule(AppModule)
    .catch(err => console.log(err));
});

这段代码会在文档加载完成后,启动Angular应用,并且任何错误(如果有)都会被捕获并打印到控制台。

3. 处理启动失败 (.catch(err => console.log(err)))

最后一部分代码是使用 .catch() 方法处理启动过程中可能出现的错误。在实际应用中,启动Angular应用可能会面临各种问题,如依赖注入失败、组件未找到、模块配置错误等。通过使用 .catch() 方法,你可以捕获这些错误并将它们记录到控制台,以便进行调试。

示例代码如下:

document.addEventListener('DOMContentLoaded', () => {
  platformBrowserDynamic().bootstrapModule(AppModule)
    .catch(err => console.log(err));
});

在这个示例中,如果在启动应用过程中出现了任何错误,错误信息将被传递给 err,然后使用 console.log() 打印到控制台,以便开发人员可以查看错误详情。

总结来说,这段代码的主要作用是等待文档加载完成后,动态启动Angular应用,并在启动过程中处理可能出现的错误。这是Angular应用的入口点,确保应用在稳定的环境中启动,并为开发人员提供了一种捕获和调试潜在问题的机制。

标签:AppModule,err,启动,Universal,渲染,应用,Angular,加载
From: https://www.cnblogs.com/sap-jerry/p/17839626.html

相关文章

  • 基于 Angular Universal 引擎进行服务器端渲染的前端应用 State Transfer 故障排查案
    笔者之前这篇掘金文章一个SAP开发工程师的2022年终总结:四十不惑提到,我目前的团队,负责开发一款基于Angular框架的电商Storefront应用。这个Storefront是一个开源的、基于Angular和Bootstrap并为SAPCommerceCloud构建的Angular应用程序。图1:SpartacusStore......
  • 关于 Angular 构建之后生成的 dist 目录和 esm2020, fesm2015 等等
    在Angular应用中,dist目录是构建应用后的输出目录,其中包含了已编译、打包和优化的应用文件。assets文件夹通常用于存放应用所需的静态资源,如图片、字体、配置文件等。esm2020、fesm2015和fesm2020是Angular构建过程中生成的文件夹,它们主要与Angular的模块加载系统和代码优化有关。......
  • 关于 Angular SSR 应用 index.html 中的 serverApp-state script 元素
    首先,我们需要了解AngularSSR(Server-SideRendering)以及SSRTransferState。AngularSSR是Angular应用程序的服务端渲染技术,它允许Angular应用程序在服务器上渲染其组件,并生成静态HTML页面,再发送给客户端。这种方法可以提高首次加载速度,提升SEO效果。而SSRTransfe......
  • Angular SSR 应用中 serverApp-state script 的工作原理介绍
    <scriptid="serverApp-state"type="application/json">元素是在服务器端渲染(Server-SideRendering,SSR)Angular应用中用于传递状态数据的重要组成部分。它被称为"SSRTransferState"机制的一部分,其作用是在服务器端生成的HTML页面中嵌入初始数据,以便客户端可以在应用初始......
  • vue+pdfh5实现将pdf渲染到页面上
    版本:[email protected]+.netCore6.0webapi方法一:通过访问后端获取二进制数据来渲染前端渲染<template><vol-boxref="box":width="width":height="height"><divid="demo"ref="render"></div></vol......
  • Angular 依赖注入系统里 Injection token APP_BASE_HREF 的使用场景
    Angular的依赖注入系统是其核心功能之一,它提供了一种优雅的方式来管理应用中的服务和组件之间的依赖关系。在Angular中,我们可以使用各种方式来提供依赖项,而APP_BASE_HREF是其中的一个依赖注入标记。APP_BASE_HREF是一个Injectiontoken,它在Angular的路由系统中扮演了重......
  • 在 Angular 中,Controller 之间通信的方式主要有三种:作用域继承仅限于上下级之间的通信
    AngularJS中control间通信最好使用什么方式?A回调B全局变量C广播D函数调用正确答案:C在Angular中,Controller之间通信的方式主要有三种:1)作用域继承。利用子Controller控制父Controller上的数据。2)注入服务。把需要共享的数据注册为一个service,在需要的Controlle......
  • Unity-Light(含Unity2021-2d项目升级Urp渲染管线)
    Unity-Light(含Unity2021-2d项目升级Urp渲染管线)普通渲染管线(比较老旧的光效升级方式,已舍弃)​ 要使场景和角色拥有光效,那就得让他们先暗下来,给他们添加相应的材质场景材质的添加​ 选中需要添加材质的场景,在右侧框内的“材质”菜单中,选中Default-Diffuse材质人物材质的添加​......
  • Cocos Creator 3.0基于PBR的物理渲染详解
    CocosCreator3.0出来以后,终于CocosCreator升级成为全新的2D/3D游戏引擎,适合2D和3D游戏开发,而3D游戏对画面效果和渲染管线的定制会有很高的需求,PBR美术工作流作为次世代主流的解决方案,今天我们来详细的分析一下基于CocosCreator的PBR物理渲染。1:计算机是如何显示颜色的讨......
  • 浏览器渲染流程
     主要是介绍浏览器从显示网页整体做了那些具体流程,主要分析渲染部分1,解析HTML解析我们的HTML,生成DOM树结构 首先会拿到html的整体的字符串,进行标记化(token)为什么要标记化,因为浏览器是不能识别这些字符串需要进行标记化的处理,本质上就是把这段字符串的html进行标签类型的拆......