Angular Component 在从后端获取数据之前呈现

时间:2021-06-21 19:09:47

标签: angular typescript

我在一页上有两个组件:父组件和子组件。 父组件发出获取请求 getCityForecast(cityCode) 并将数据绑定到子组件。

问题是子组件在父组件之前重新加载。并且没有填充数据。我该如何解决?

父组件

HTML

<div class="search-field">
  <input type="search" placeholder="Search..." [(ngModel)]="cityInput" (ngModelChange)="getAutoCompleteResults()">
  <button class="search-button">
    <svg id="search-icon" class="search-icon" viewBox="0 0 24 24">
      <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>
      <path d="M0 0h24v24H0z" fill="none"/>
    </svg>
  </button>
  <div *ngIf="hasSearchResults()">
    <p *ngFor="let city of autoCompleteSearchResults" (click)="cityChoice(city.LocalizedName, city.Key); getCityForecast(city.Key)">{{city.LocalizedName}}</p>
  </div>
</div>

<app-todays-forecast
  [city]="cityDetails"
  [todaysForecast]="todaysForecast">
</app-todays-forecast>

TS

import { Component, OnInit } from '@angular/core';
import { DataFetchService } from '../services/data-fetch.service';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-local-forecast',
  templateUrl: './local-forecast.component.html',
  styleUrls: ['./local-forecast.component.scss']
})
export class LocalForecastComponent implements OnInit {

  autoCompleteSearchResults: any;
  cityInput: string = '';
  cityDetails: any = {};
  defaultCityCode = 210841;
  defaultCityName: string = 'Tel-Aviv';
  todaysForecast: any;

  constructor(private fetchData: DataFetchService,
    private http: HttpClient) { }

  ngOnInit(): void {
    this.cityDetails.name = this.defaultCityName;
    this.getCityForecast(this.defaultCityCode);
    console.log(this.todaysForecast);
  }

  hasSearchResults() {
    return this.autoCompleteSearchResults?.length > 0;
  }

  cityChoice(name, key) {
    this.cityDetails.name = name;
    this.cityDetails.key = key;
  }

  getAutoCompleteResults() {
    this.fetchData.fetchAutoCompleteResults(this.cityInput)
      .subscribe(
        result => { this.autoCompleteSearchResults = result },
        err => console.log(`we have an error: ${err}`)
      )
  }

  getCityForecast(cityCode) {
    this.fetchData.getCityForecast(cityCode)
    .subscribe(
      result => this.todaysForecast = result[0],
      err => console.log(`we have an error: ${err}`)
    );
  }

子组件

HTML

<h1>Today's Weather in {{city.name}}</h1>
<p>Temperature: {{temperature}}°С</p>
<p>Weather: {{conditions}}</p>

TS

import { Component, OnInit, Input } from '@angular/core';
import { DataFetchService } from 'src/app/services/data-fetch.service';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-todays-forecast',
  templateUrl: './todays-forecast.component.html',
  styleUrls: ['./todays-forecast.component.scss']
})
export class TodaysForecastComponent implements OnInit {

  @Input() city: any;
  @Input() todaysForecast: any;

  temperature: any;
  conditions: any;

  constructor( public fetchData: DataFetchService) { }

  ngOnInit(): void {
    console.log('this.todaysForecast >>>', this.todaysForecast);
    this.temperature = this.todaysForecast?.Temperature.Metric.Value;
    this.conditions = this.todaysForecast?.WeatherText;
  }

}

3 个答案:

答案 0 :(得分:1)

如果您想在呈现组件之前获取数据,您可以使用解析器。

https://angular.io/api/router/Resolve

答案 1 :(得分:1)

不要使用 ngOnInit,而是使用 @Input 中的“setter”

@Input() todaysForecast(value){
    this.temperature = value.Temperature.Metric.Value;
    this.conditions = value.WeatherText;
    //is you need it you can also use another variable "_todayForecast
    //this._todayForecast=value
}
//and a getter
get todayForecast(){
   return this._todayForecast
}

实现 OnChanges

export class TodaysForecastComponent implements OnChanges {
  @Input() todaysForecast;

  ngOnChanges(changes: SimpleChanges) {
    // changes.prop contains the old and the new value...
  }
}

答案 2 :(得分:1)

有几种方法可以做到:

  • 有条件地在父模板 *ngIf="data" 中显示子组件,其中 data 是从后端检索的数据
  • 使子组件以特定方式处理 nullundefined
  • 在子组件中传播 Observable(通常更复杂,不符合智能/哑组件原则)