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

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

嗨我正在使用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方法来获取数据。角度通用渲染确实调用此函数。呼叫已作出,但不等待响应返回。它改为返回初始数据。在服务器控制台中一段时间​​后,我确实看到响应已经回到服务器。但到那时,角度普遍已经回归。

请帮忙解决这个问题。

angular angular-universal
1个回答
1
投票

我知道这个问题已存在一段时间了。这就是我们在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({});
        });
    }
  }
}

只要返回Observable,上面的服务就可以是任何异步数据提取器

StateTransfer握手将迫使解析器等待API结果。问题是,没有超时,如果您的API有任何问题,它看起来好像是最终用户。

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

path: 'campaigns',
children: [
  {
    path: ':dealId',
    component: EcommerceProductDetails,
    resolve: { result: ProductDetailsResolver },
    runGuardsAndResolvers: 'paramsOrQueryParamsChange'
  }
]

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

ngOnInit() {
  this.route.data.subscribe(data => {
    this.deal = <IDeal>data.result._source;
  });
}
© www.soinside.com 2019 - 2024. All rights reserved.