【问题标题】:Angular component rendered before API response completed在 API 响应完成之前渲染的 Angular 组件
【发布时间】:2020-11-16 12:04:47
【问题描述】:

我正在开发一个 Angular 8 的应用程序。 我有一个父组件(Bid)包含一些子组件(service1,service2),每个子组件根据数据动态加载一些数据,这些数据来自一个API。我在父组件(Bid)中调用这个 API。

问题是有时控​​件在 API 完成之前呈现,因此页面显示为空。

我尝试在 ngOnInit() 和 constructor() 中调用 API,但结果是一样的。

组件层次结构如下:

RequestDetails ==> 出价 ==> (Service1, Service2)

请求详情:

constructor(private activatedRoute: ActivatedRoute, public common: CommonService, public bidService: BidsService) {
this.activatedRoute.paramMap.subscribe((param) => {
  
  let bidID = param.get('bidId');
  if (bidID != null) {
    this.bidService.setMode('edit');
    this.getRequestDetails(param.get('id')).then(res => this.bidService.fillEditFields(bidID)) // Get fields values
  }
  else{
    this.getRequestDetails(param.get('id'));
    this.bidService.setMode('create');
  }
})}

出价:

constructor(public common: CommonService, public bidsService: BidsService, private activatedRoute: ActivatedRoute, public router: Router) {
this.loading = true;
this.bidsService.bidValue.subscribe(p => this.bid = p);
this.bidsService.bidRequestDetails.subscribe(p => this.bidRequestDetails = p);}

出价HTML:

<app-net-rate-item [isFCL]="isFCL" *ngFor="let container of filterNetRate(getCurrentEditNetRate(),1)"
    [cargoDetailsId]="0" [netRateContainerType]="container.netRateContainerType"
    [netRateContainerTypeId]="container.netRateContainerTypeId" [netRateContainerAmount]="container.netRateAmount"
    (valueChange)="getNetRateValue($event, container.netRateId, 1)" [netRateType]="1" [sourceType]="sourceType"
    [disabled]="sourceType === 1 ? bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled"
    [required]="(sourceType === 1 ? !bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : !bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled)"
    [validate]="validateEvent" [value]="container">
  </app-net-rate-item>

【问题讨论】:

  • 添加 *ngIf 用于获取数据时要显示的组件或任何 HTML 元素
  • @yazan,我用我的 Html 代码编辑了帖子,我正在使用 *ngFor 循环 API 的结果
  • 您希望 app-net-rate-item 在 this.bidRequestDetails 获得所需值时显示?
  • @yazan 是的,没错。

标签: javascript angular api angular8


【解决方案1】:

您可以使用 *ngIf 来隐藏/显示组件或任何 HTML 元素,在您的示例中,您必须提供一个布尔属性来获取当前状态,如下所示:

Bid.ts

    show = false;
    constructor(public common: CommonService, public bidsService: BidsService, private activatedRoute: ActivatedRoute, public router: Router) {
    this.loading = true;
    this.bidsService.bidValue.subscribe(p => this.bid = p);
    this.bidsService.bidRequestDetails.subscribe(p => {
this.bidRequestDetails = p;
this.show = true;  // to update the state
});}

出价 Html:

<div *ngIf='show'>
    <app-net-rate-item [isFCL]="isFCL" *ngFor="let container of filterNetRate(getCurrentEditNetRate(),1)"
        [cargoDetailsId]="0" [netRateContainerType]="container.netRateContainerType"
        [netRateContainerTypeId]="container.netRateContainerTypeId" [netRateContainerAmount]="container.netRateAmount"
        (valueChange)="getNetRateValue($event, container.netRateId, 1)" [netRateType]="1" [sourceType]="sourceType"
        [disabled]="sourceType === 1 ? bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled"
        [required]="(sourceType === 1 ? !bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : !bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled)"
        [validate]="validateEvent" [value]="container">
      </app-net-rate-item>
</div>

顺便提一下,您可以添加 &lt;ng-container&gt; 而不是外部 div 元素,因为它是一个不会干扰样式或布局的分组元素,并且 Angular 不会将其放入 DOM .

或者您也可以在 Bid.Html 中使用 hidden:

    <app-net-rate-item [hidden]='!show' [isFCL]="isFCL" *ngFor="let container of filterNetRate(getCurrentEditNetRate(),1)"
        [cargoDetailsId]="0" [netRateContainerType]="container.netRateContainerType"
        [netRateContainerTypeId]="container.netRateContainerTypeId" [netRateContainerAmount]="container.netRateAmount"
        (valueChange)="getNetRateValue($event, container.netRateId, 1)" [netRateType]="1" [sourceType]="sourceType"
        [disabled]="sourceType === 1 ? bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled"
        [required]="(sourceType === 1 ? !bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : !bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled)"
        [validate]="validateEvent" [value]="container">
      </app-net-rate-item>

【讨论】:

  • 当我尝试这个解决方案时,我得到了这个错误“模板解析错误:一个元素上不能有多个模板绑定。只使用一个前缀为 * 的属性”
  • 只需添加一个外部 div 以包含
  • 非常感谢,它终于可以工作了,但我不得不在父组件中添加 (*ngIf),因为我有很多子组件。
猜你喜欢
  • 2018-09-19
  • 2021-05-18
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-21
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
相关资源
最近更新 更多