簡體   English   中英

如何將* ngIf用於異步http.get數據請求-Angular 2

[英]How to use *ngIf for async http.get data request - Angular 2

我有一個Web應用程序,該應用程序正在從多個api檢索數據,並且應該將數據使用到一些圖表中。 問題在於,當圖表被渲染時,來自api的數據還沒有。 我嘗試使用.then()方法,但它告訴我, property then does not exist on type voidproperty then does not exist on type void 此外,在此答案之后 ,我嘗試使用ngIf方法,但也不起作用。 你知道我該怎么解決嗎?

以下是我的組件和組件模板。

app.component.ts

import { Component } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/Rx';

import * as moment from 'moment'; 

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Mimesi dashboard graphs';

  //COUNTS
  public countIndexerMetaApi; //array of one number populated from http.get
  public countIndexerMetaNumber; //number extracted into array and stored as an int
  public countIndexerMetaArray; //array to store countNumber afterwards

  public countIndexerServedApi; 
  public countIndexerServedNumber; 
  public countIndexerServedArray; 

  public countRealTimeServedApi; 
  public countRealTimeServedNumber; 
  public countRealTimeServedArray;

  //DATES
  public dateIndexerMetaToStore; //date got from moment method that needs to be stored
  public dateIndexerMetaArray; //array to store dates for graph label

  public dateIndexerServedToStore;
  public dateIndexerServedArray;

  public dateRealTimeServedToStore;
  public dateRealTimeServedArray;

  //API LINKS
  private apiCountIndexerMetaUrl: string = 'http://localhost:3000/api/countIndexerMetaApi';
  /*      TODO - API FOR COUNT OF OTHER TWO TABLES      */
  private apiCountIndexerServedUrl: string = 'http://localhost:3000/api/countIndexerServedApi';
  private apiCountRealTimeServedUrl: string = 'http://localhost:3000/api/countRealTimeServedApi';

  //VARIABLE FOR TIMEOUT
  public isDataAvailable:boolean = false;

  constructor(private http:Http) { 
    let now = moment.locale("it");

    //COUNT
    this.countIndexerMetaApi = 0;
    this.countIndexerMetaNumber = 0;
    this.countIndexerMetaArray = [];

    this.countIndexerServedApi = 0;
    this.countIndexerServedNumber = 0;
    this.countIndexerServedArray = []

    this.countRealTimeServedApi = 0;
    this.countRealTimeServedNumber = 0;
    this.countRealTimeServedArray = []

    //DATES
    this.dateIndexerMetaToStore = "";
    this.dateIndexerMetaArray = [];

    this.dateIndexerServedToStore = "";
    this.dateIndexerServedArray = [];

    this.dateRealTimeServedToStore = "";
    this.dateRealTimeServedArray = [];
  }

  ngOnInit() {
    this.getIndexerMetaCount();
    this.getIndexerServedCount();
    this.getRealTimeServedCount();
  }

  //COUNT
  getIndexerMetaCount(){
    this.http.get(this.apiCountIndexerMetaUrl)
        .map((res: Response) => res.json())
        .subscribe(
            data => {
                console.log(this.countIndexerMetaApi = data.map(countIndexerMetaApiObj => countIndexerMetaApiObj.countIndexerMetaApi))
            },
        );
    //this.countIndexerMetaNumber = this.countIndexerMetaApi[0]; //<-- timing problem since this.count is not yet got from http.get() so it seems undefined
    //this.countIndexerMetaArray.push(this.countIndexerMetaNumber); // problem follows through
  }
  printCountIndexerMetaArray(){
    this.countIndexerMetaApi.forEach(element => {
      console.log(element);
    });
  }

  getIndexerServedCount(){
    this.http.get(this.apiCountIndexerServedUrl)
        .map((res: Response) => res.json())
        .subscribe(
            data => {
                console.log(this.countIndexerServedApi = data.map(countObj => countObj.countIndexerServedApi))
            },
        );
    //this.countIndexerServedNumber = this.countIndexerServedApi[0]; //<-- timing problem since this.count is not yet got from http.get() so it seems undefined
    //this.countIndexerServedArray.push(this.countIndexerServedNumber); // problem follows through
  }
  printCountIndexerServedArray(){
    this.countIndexerServedApi.forEach(element => {
      console.log(element);
    });
  }

  getRealTimeServedCount(){
    this.http.get(this.apiCountRealTimeServedUrl)
        .map((res: Response) => res.json())
        .subscribe(
            data => {
                console.log(this.countRealTimeServedApi = data.map(countObj => countObj.countRealTimeServedApi))
            },
        );
    //this.countRealTimeServedNumber = this.countRealTimeServedApi[0]; //<-- timing problem since this.count is not yet got from http.get() so it seems undefined
    //this.countRealTimeServedArray.push(this.countRealTimeServedNumber); // problem follows through
  }
  printRealTimeServedArray(){
    this.countRealTimeServedApi.forEach(element => {
      console.log(element);
    });
  }

  //DATES
  dateIndexerMeta() {
    this.dateIndexerMetaToStore = moment().add(-122, 'days');
    this.dateIndexerMetaArray.push(this.dateIndexerMetaToStore);
  }

  dateIndexerServed() {
    this.dateIndexerServedToStore = moment().add(-122, 'days');
    this.dateIndexerServedArray.push(this.dateIndexerServedToStore);
  }

  dateRealTimeServed() {
    this.dateRealTimeServedToStore = moment().add(-122, 'days');
    this.dateRealTimeServedArray.push(this.dateRealTimeServedToStore);
  }

  //TIMEOUT TRIAL
  timeoutTrial(){
    console.log(this.isDataAvailable);
    setTimeout(function() {this.isDataAvailable = true; 
      console.log(this.isDataAvailable);
    }, 5000); //<-- timeout works but other functions don't refresh even if isDataAvailable changed
  }

  /*      CHARTS      */

  //DATA
  public lineChartData:Array<any> = [
    {data: this.countIndexerMetaArray, label: 'Indexer meta served links'},
  ];

  public lineChartData1:Array<any> = [
    {data: this.countIndexerServedArray, label: 'Indexer served links'},
  ];

  public lineChartData2:Array<any> = [
    {data: this.countRealTimeServedArray, label: 'Real-Time served links'},
  ];

  //LABELS
  public lineChartLabels:Array<any> = this.dateIndexerMetaArray;

  public lineChartLabels1:Array<any> = this.dateIndexerServedArray;

  public lineChartLabels2:Array<any> = this.dateRealTimeServedArray; 

  //OPTIONS
  public lineChartOptions:any = {
    responsive: true,

    scales: {
      xAxes: [{
        type: 'time',
        time: {
          displayFormats: {
            'millisecond': 'DD MMM',
            'second': 'DD MMM',
            'minute': 'DD MMM',
            'hour': 'DD MMM',
            'day': 'DD MMM',
            'week': 'DD MMM',
            'month': 'DD MMM',
            'quarter': 'DD MMM',
            'year': 'DD MMM',
          }
        }
      }],
    },

  };

  public lineChartLegend:boolean = true;
  public lineChartType:string = 'line';

  //COLORS
  public lineChartColors:Array<any> = [
    { // grey
      backgroundColor: 'rgba(255,55,55,0.2)',
      borderColor: 'rgba(255,55,55,1)',
      pointBackgroundColor: 'rgba(255,55,55,1)',
      pointBorderColor: '#fff',
      pointHoverBackgroundColor: '#fff',
      pointHoverBorderColor: 'rgba(255,55,55,0.8)'
    },
  ];

  //EVENTS
  public chartClicked(e:any):void {
    console.log(e);
  }

  public chartHovered(e:any):void {
    console.log(e);
  }
}

app.component.html

<div class="container">


<div class="front-end-app">
    <ul>
      <h3>Count Indexer Meta:</h3>
      <li *ngFor="let countIndexerMetaNumber of countIndexerMetaApi">
        {{countIndexerMetaNumber}}
      </li>
      <h3>Count Indexer Served:</h3>
      <li *ngFor="let countIndexerServedNumber of countIndexerServedApi">
        {{countIndexerServedNumber}}
      </li>
      <h3>Count Real Time Served:</h3>
      <li *ngFor="let countRealTimeServedNumber of countRealTimeServedApi">
        {{countRealTimeServedNumber}}
      </li>
    </ul>
    <hr>

    <div class="head">
      <h1>{{title}}</h1>
    </div>
    <hr>
    <div class="row">
      <div class="col-md-6">
        <div class="card">
          <div class="card-block">
            <canvas baseChart width="600" height="400"
                  [datasets]="lineChartData"
                  [labels]="lineChartLabels"
                  [options]="lineChartOptions"
                  [colors]="lineChartColors"
                  [legend]="lineChartLegend"
                  [chartType]="lineChartType"
                  (chartHover)="chartHovered($event)"
                  (chartClick)="chartClicked($event)"></canvas>
          </div>
        </div>
      </div>
      <div class="col-md-6">
        <div class="card">
          <div class="card-block">
            <canvas baseChart width="600" height="400"
                    [datasets]="lineChartData1"
                    [labels]="lineChartLabels1"
                    [options]="lineChartOptions"
                    [colors]="lineChartColors"
                    [legend]="lineChartLegend"
                    [chartType]="lineChartType"
                    (chartHover)="chartHovered($event)"
                    (chartClick)="chartClicked($event)"></canvas>
          </div>
        </div>
      </div>
      <div class="col-md-6 offset-md-3">
        <div class="card">
          <div class="card-block">
            <canvas baseChart width="600" height="400"
                    [datasets]="lineChartData2"
                    [labels]="lineChartLabels2"
                    [options]="lineChartOptions"
                    [colors]="lineChartColors"
                    [legend]="lineChartLegend"
                    [chartType]="lineChartType"
                    (chartHover)="chartHovered($event)"
                    (chartClick)="chartClicked($event)"></canvas>
          </div>
        </div>
      </div>
    </div>
  </div>
  <button type="button" class="btn btn-primary" (click)="printCountIndexerMetaArray()"> Click to print count indexer meta array</button>
  <button type="button" class="btn btn-primary" (click)="printCountIndexerServedArray()"> Click to print count indexer served array</button>
  <button type="button" class="btn btn-primary" (click)="printRealTimeServedArray()"> Click to print count real time served array</button>
</div>

對於任何問題或進一步的解釋,請發表評論,我會立即回答。 謝謝!

只需使用布爾值顯示加載即可。

public isloading = true; 

在您的http調用中,一旦獲得所需的所有數據,請將其設置為false。

this.http.get(this.apiCountRealTimeServedUrl)
        .map((res: Response) => res.json())
        .subscribe(
            data => {
                this.countRealTimeServedApi = 
                    data.map(countObj => countObj.countRealTimeServedApi);
                this.isloading= false;
            },
        );

在您的HTTP中有ngIf作為isloading部分

<div *ngIf="isloading" > loading .... </div>
<div *ngIf="!isloading" > 
   <!-- show the chart contents -->
</div>

如果您有多個HTTP調用,請使用&&

 <div *ngIf="isIndexMetaCountloading 
            || isIndexerServedCountLoading 
            || isRealTimeServedCountLoading" > 
   loading ...
</div>

<div *ngIf="!isIndexMetaCountloading 
            && !isIndexerServedCountLoading 
            && isRealTimeServedCountLoading" > 
   <!-- show the chart contents -->
</div>

你忘了實現OnInit [ https://angular.io/guide/lifecycle-hooks][1]

export class AppComponent implements OnInit{

嘗試對此組件使用Resolver [ https://angular.io/api/router/Resolve][2]

我沒有弄清楚您的問題是什么,請您再澄清一下。 但是如果您的問題在於這些行

this.countIndexerServedNumber = this.countIndexerServedApi[0]; 
  //<-- timing problem since this.count is not yet 
  // got from http.get() so it seems undefined
this.countIndexerServedArray.push(this.countIndexerServedNumber); 
   // problem follows through

則它不起作用,因為get方法異步工作,因此this.countIndexerServedApi尚未初始化。 因此,要解決此問題,您應該將這些語句移到this.countIndexerServedApi塊內,然后僅在this.countIndexerServedApi初始化后才執行這些語句。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM