预渲染实际上如何工作?

Sas*_*sxa 14 angular

服务器端渲染的资源很少,事实上,我找不到任何能清楚解释实际工作方式的东西.我已经看过一些回购,试图遵循代码,但没有设法弄清楚它的要点.如果我正常运行角度,我基本上知道会发生什么:

  1. 加载HTML文件: <html><body><my-app>...</my-app><SCRIPTS/></body></html>
  2. 脚本被加载......
  3. Angular处理代码,并替换<my-app>内部的所有好东西.

对于这个程序:

@Component({
  selector: 'my-app'
  template: `<p *ngFor="let i of items">{{ i }}</p>`,
})
export class AppComponent {
  items = [1, 2, 3];
}
Run Code Online (Sandbox Code Playgroud)

我可以看到检查html(plunker)并看到:

<my-app>
  <!--template bindings={
    "ng-reflect-ng-for-of": "1,2,3"
  }-->
  <p>1</p>
  <p>2</p>
  <p>3</p>
</my-app>
Run Code Online (Sandbox Code Playgroud)

到目前为止都清楚了!(:

但是预渲染会发生什么?如果我创建这样的文件:

<html>
<body>
  <my-app>
    <!--template bindings={
        "ng-reflect-ng-for-of": "1,2,3"
      }-->
    <p>1</p>
    <p>2</p>
    <p>3</p>
  </my-app>
  <SCRIPTS/>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

一旦加载脚本,Angular会做什么?我可以使用这个HTML而不是第一个吗?如果有人了解这个过程是如何工作的,请分享(;关于这些东西的任何信息都会有用......我可以复制outerHTML,并将其作为我的"预渲染页面"吗?...像这样:

复制outerHTML

如果没有,为什么?我正在寻找这个过程的本质,一个可以手工编写的例子......

Ale*_*ets 16

使用服务器端呈现,页面呈现两次:在服务器上,因此您可以很早地看到呈现的视图,然后在客户端上 - 在加载应用程序之后.

  • 在服务器端,您可以使用angular-universal在给定路径URL的情况下呈现应用程序的任何视图;
  • 在客户端上,您的应用程序正常引导 - 客户端呈现的视图被放入应用程序根标记并替换服务器呈现的视图.客户端发生的唯一神奇之处是通过通用项目的preboot.js模块将状态转移到客户端应用程序,这是通过记录在服务器呈现的视图上触发的事件然后在客户端呈现的情况下重放它们来完成的.应用程序加载后的视图.因此,如果input在加载应用程序之前在框中键入内容,则preboot.complete()在客户端呈现的视图替换服务器呈现的视图之后,将通过命令重播按键.

你的问题:

一旦加载脚本,Angular会做什么?

您的应用程序正常引导,<my-app></my-app>标记的内容将由客户端呈现的视图替换.

我可以复制outerHTML,并将其作为我的"预渲染页面"吗?

是.但是,angular-universal最好使用模块,因此您可以动态渲染任何路径后面的视图.

至于样本,这里是Angular 2 Universal Starter,它是一个示例应用程序,演示了实际的通用事物.玩它:

  • 更改应用程序加载时的字符串'This was rendered from the server!',dist/server/index.js以查看它是否已恢复.这意味着在呈现客户端视图后该语句变为谎言.
  • 启用preboot并推迟preboot.complete()查看它的实际操作(在input框中输入内容):

    SRC/main.node.ts

    let config: ExpressEngineConfig = {
        // ...
        preboot: { appRoot: 'app' } // your top level app component selector
    };
    
    Run Code Online (Sandbox Code Playgroud)

    SRC/client.ts

    ngApp()
    .then(function() {
      setTimeout(function() {
        preboot.complete();
      }, 5000);
    });
    
    Run Code Online (Sandbox Code Playgroud)

这里是在客户端上使用预启动静态提供"预渲染"视图的简单演示.在app引导之前有5秒的延迟,以查看预启动的运行情况.

我不是有角度的专家,所以,如果我错了,请纠正我.我的判断依据是阅读以下资源:


Ang*_*hub 1

我认为你必须使用angular2-universal-preview才能在服务器端渲染应用程序:

    import * as express from 'express';
    import {ng2engine} from 'angular2-universal-preview';

    // Angular 2
    import {App} from './src/app';

    let app = express();

    // Express View
    app.engine('.ng2.html', ng2engine);
    app.set('views', __dirname);
    app.set('view engine', 'ng2.html');


    // static files
    app.use(express.static(__dirname));


    app.use('/', (req, res) => {
      res.render('index', { App });
    });



    app.listen(3000, () => {
      console.log('Listen on http://localhost:3000');
    });`
Run Code Online (Sandbox Code Playgroud)