服务器端呈现不等待API调用完成

Ani*_*ket 8 angular-universal angular

嗨我正在使用Angular版本4.3,我已经实现了本文中提到的服务器端呈现.

https://medium.com/@cyrilletuzi/angular-server-side-rendering-in-node-with-express-universal-engine-dce21933ddce

当我点击服务器URL以使服务器端呈现HTML时,组件的初始数据确实出现,这些数据是静态的,不依赖于任何API调用.

但问题是渲染不包含完成AJAX请求后应该存在的数据.

我在我的组件的ngOnInit方法中编写了API调用.它调用一个服务,该服务调用angular的http服务的get方法来获取数据.角度通用渲染确实调用此函数.呼叫已作出,但不等待响应返回.它改为返回初始数据.在服务器控制台中一段时间​​后,我确实看到响应已经回到服务器.但到那时,角度普遍已经回归.

请帮忙解决这个问题.

Fra*_*ani 2

我知道这个问题已经存在了一段时间。这就是我们如何使用解析器在LastCall.cc中找到解决方法(尽管性能不是很好)

import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import {
  Resolve,
  RouterStateSnapshot,
  ActivatedRouteSnapshot
} from '@angular/router';
import { makeStateKey, TransferState } from '@angular/platform-browser';
import { SearchService } from '@app/services/search.service';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';

@Injectable()
export class ProductDetailsResolver implements Resolve<any> {
  private result: any;
  constructor(
    private readonly state: TransferState,
    private search: SearchService
  ) { }

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> {
    const id = route.paramMap.get('dealId');
    const RESULT_KEY = makeStateKey<any>('product-details-resolver.result' + id);
    if (this.state.hasKey(RESULT_KEY)) {
      const res = of(this.state.get<any>(RESULT_KEY, null));
      this.state.remove(RESULT_KEY);
      return res;
    } else {
      this.state.onSerialize(RESULT_KEY, () => this.result);
      return this.search.searchDealById(id)
        .do(result => {
          this.result = result;
        }).catch((error) => {
          console.log('API Error --> ', error);
          this.result = {};
          return Observable.of({});
        });
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

上面的服务可以是任何异步数据获取器,只要它返回一个Observable

握手StateTransfer将强制解析器等待 API 结果。问题是,没有超时,如果您的 API 有任何问题,对于最终用户来说似乎是挂起的。

以下是使用解析器实现路由的方法:

path: 'campaigns',
children: [
  {
    path: ':dealId',
    component: EcommerceProductDetails,
    resolve: { result: ProductDetailsResolver },
    runGuardsAndResolvers: 'paramsOrQueryParamsChange'
  }
]
Run Code Online (Sandbox Code Playgroud)

以下是如何获取组件中的数据:

ngOnInit() {
  this.route.data.subscribe(data => {
    this.deal = <IDeal>data.result._source;
  });
}
Run Code Online (Sandbox Code Playgroud)