[英]Wait before display data with {HttpClient} - typescript - Angular
4 天以來,我正在嘗試顯示數據,但沒有任何運行。 我的目標是從工廠的內部服務器接收數據。 所以,一些西門子 CPU 在 CSV 文件中發送數據,我在
線路服務.ts
import {Subject} from 'rxjs';
import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
@Injectable()
export class LineService{
public lines: RcvData[] = [];
constructor(private http: HttpClient) {
this.getData();
}
lineSubject = new Subject<any[]>();
getData(): void {
const lists: string[] = [
'assets/donnee-l1.csv',
'assets/donnee-l2.csv',
'assets/donnee-l3.csv',
'assets/donnee-l4.csv',
'assets/donnee-l5.csv',
'assets/donnee-l6.csv'
];
for (const list of lists) {
this.http.get(list, {responseType: 'text'})
.subscribe(data => {
const csvToRowArray = data.split('\n');
const lastRow = csvToRowArray[csvToRowArray.length - 2];
const row = lastRow.split(',');
this.lines.push(new RcvData(
parseInt(row[0], 10),
row[1], row[2], row[3], row[4], row[5],
parseInt(row[6], 10),
parseInt(row[7], 10),
parseInt(row[8], 10),
parseInt(row[9], 10),
parseFloat(row[10]),
parseFloat(row[11]),
parseFloat(row[12]),
parseFloat(row[13]),
parseFloat(row[14]))
);
if(this.lines.length === 6){
this.isLoading = true;
}
console.log(this.isLoading);
console.log(this.lines.length);
}, error => {
console.log(error);
});
}
}
emitLineSubject(): void {
this.lineSubject.next(this.lines.slice());
}
getLineById(id: number): RcvData{
const line = this.lines.find(
(lineObject) => {
return lineObject.id === id;
}
);
return line;
}
}
class RcvData{
id: number;
date: string;
utcTime: string;
refCharge: string;
refDecharge: string;
quantiteEnCours: string;
quantiteHoraireReel: number;
quantiteHoraireTheorique: number;
quantitePosteReel: number;
quantitePosteTheorique: number;
trpHeureReel: number;
trpPosteReel: number;
trpObjectif: number;
consoAir: number;
consoElec: number;
constructor(
id: number,
date: string,
utcTime: string,
refCharge: string,
refDecharge: string,
quantiteEnCours: string,
quantiteHoraireReel: number,
quantiteHoraireTheorique: number,
quantitePosteReel: number,
quantitePosteTheorique: number,
trpHeureReel: number,
trpPosteReel: number,
trpObjectif: number,
consoAir: number,
consoElec: number)
{
this.id = id;
this.date = date;
this.utcTime = utcTime;
this.refCharge = refCharge;
this.refDecharge = refDecharge;
this.quantiteEnCours = quantiteEnCours;
this.quantiteHoraireReel = quantiteHoraireReel;
this.quantiteHoraireTheorique = quantiteHoraireTheorique;
this.quantitePosteReel = quantitePosteReel;
this.quantitePosteTheorique = quantitePosteTheorique;
this.trpHeureReel = trpHeureReel;
this.trpPosteReel = trpPosteReel;
this.trpObjectif = trpObjectif;
this.consoAir = consoAir;
this.consoElec = consoElec;
}
}
現在,在 this.ts 中,我將CSV 數據拆分為我的 6 條生產線的 object。 我為我的 html 頁面發送數據,以顯示它。 我用這個組件讀取數據:
單行組件.ts
import { Component, OnInit } from '@angular/core';
import { LineService } from '../services/line.service';
import { ActivatedRoute } from '@angular/router';
import {async} from 'rxjs-compat/scheduler/async';
@Component({
selector: 'app-single-line',
templateUrl: './single-line.component.html',
styleUrls: ['./single-line.component.scss']
})
export class SingleLineComponent implements OnInit {
name = 'Ligne...';
status = 'éteint';
date_jour = '2021-01-01';
heure_act = '00:00:00';
reference_charge = 'ST00S00';
reference_decharge = 'ST11S11';
quantite_produite = '1/1000';
quantite_h_reel = 0;
quantite_h_th = 0;
quantite_p_reel = 0;
quantite_p_th = 0;
trp_h_reel = 0;
trp_p_reel = 0;
trp_objectif = 0;
conso_air = 0;
conso_elec = 0;
private activatedRoute: ActivatedRoute;
constructor(private lineService: LineService,
private route: ActivatedRoute) {
this.activatedRoute = route;
}
ngOnInit(): void {
this.activatedRoute.params.subscribe(params => {
const id = params.id;
this.name = this.lineService.getLineById(+id).refCharge;
this.status = this.lineService.getLineById(+id).date;
this.date_jour = this.lineService.getLineById(+id).date;
this.heure_act = this.lineService.getLineById(+id).utcTime;
this.reference_charge = this.lineService.getLineById(+id).refCharge;
this.reference_decharge = this.lineService.getLineById(+id).refDecharge;
this.quantite_produite = this.lineService.getLineById(+id).quantiteEnCours;
this.quantite_h_reel = this.lineService.getLineById(+id).quantiteHoraireReel;
this.quantite_h_th = this.lineService.getLineById(+id).quantiteHoraireTheorique;
this.quantite_p_reel = this.lineService.getLineById(+id).quantitePosteReel;
this.quantite_p_th = this.lineService.getLineById(+id).quantitePosteTheorique;
this.trp_h_reel = this.lineService.getLineById(+id).trpHeureReel;
this.trp_p_reel = this.lineService.getLineById(+id).trpPosteReel;
this.trp_objectif = this.lineService.getLineById(+id).trpObjectif;
this.conso_air = this.lineService.getLineById(+id).consoAir;
this.conso_elec= this.lineService.getLineById(+id).consoElec;
});
}
}
最后,我的 HTML 頁面:
<div class="container-fluid">
<div [ngClass]="{'list-group-item': true,
'list-group-item-success': status === 'allumé',
'list-group-item-danger' : status === 'éteint',
'list-group-item-warning' : status === 'changement'
}">
<h1>
<p *ngIf="status === 'allumé'"> {{ name }} | en production
<span class="glyphicon glyphicon-ok"></span>
</p>
<p *ngIf="status === 'éteint'">{{ name }} | à l'arrêt
<span class="glyphicon glyphicon-remove"></span>
</p>
<p *ngIf="status === 'changement'">{{ name }} | changement en cours
<span class="glyphicon glyphicon-refresh"></span>
</p>
</h1>
<div class="row h3">
<div class="col-sm-6 list-group-item-text text-center">
<p> Référence en cours de chargement : {{ reference_charge }}</p>
<p> Référence en cours de déchargement : {{ reference_decharge }}</p>
</div>
</div>
<div class="row list-group-item-text text-center h4">
<div class="col-sm-3 text-center">
<p>Quantité de pièces totale : {{ quantite_produite }}</p>
</div>
<div class="col-sm-3 text-center">
<p>Pièces produites dans l'heure : {{ quantite_h_reel }}</p>
</div>
<div class="col-sm-3 text-center">
<p>Pièces à produire par heure : {{ quantite_h_th }}</p>
</div>
<div class="col-sm-3 text-center">
<p>Pièces produites sur le poste : {{ quantite_p_reel }}</p>
</div>
<div class="col-sm-3 text-center">
<p>Pièces à produire sur un poste : {{ quantite_p_th }}</p>
</div>
<div class="col-sm-3 text-center">
<p>TRP de l'heure: {{ trp_h_reel }}</p>
</div>
<div class="col-sm-3 text-center">
<p>TRP du poste: {{ trp_p_reel }}</p>
</div>
<div class="col-sm-3 text-center">
<p>TRP Objectif: {{ trp_objectif }}</p>
</div>
<div class="col-sm-3 text-center">
<p>Consommation d'air: {{ conso_air }}</p>
</div>
<div class="col-sm-3 text-center">
<p>Consommation électrique : {{ conso_elec }}</p>
</div>
</div>
<button class="btn btn-primary" routerLink="/lines">Retour</button>
</div>
<app-view-graph></app-view-graph>
</div>
但問題是,當我重新加載頁面時,出現錯誤:TypeError: Cannot read property '...' of undefined。 這是因為頁面正在加載,然后讀取數據運行。 如果我通過導航欄更改頁面並返回正確的頁面,則數據就在這里。 我只想在數據存在時顯示頁面。
我嘗試使用 Promise、Async、Await、SpinnerLoad,但它不起作用。
歡迎任何幫助。 謝謝
我建議讓您的解決方案更具反應性。
首先,不要使用 for 循環遍歷所有鏈接,然后將它們推送到lines[]
中,我建議采用以下方法
import {BehaviourSubject} from 'rxjs'; import {HttpClient} from '@angular/common/http'; import {Injectable} from '@angular/core'; @Injectable() export class LineService{ constructor(private http: HttpClient) { this.getData(); } lineSubject = new BehaviourSubject<RcvData[]>([]); getData(): void { const lists: string[] = [ 'assets/donnee-l1.csv', 'assets/donnee-l2.csv', 'assets/donnee-l3.csv', 'assets/donnee-l4.csv', 'assets/donnee-l5.csv', 'assets/donnee-l6.csv' ]; combineLatest(lists.map(list => this.http.get(list, {responseType: 'text'}))).subscribe(listResults => { const parsedListResults = listResults.map(data => { const csvToRowArray = data.split('\n'); const lastRow = csvToRowArray[csvToRowArray.length - 2]; const row = lastRow.split(','); return new RcvData( parseInt(row[0], 10), row[1], row[2], row[3], row[4], row[5], parseInt(row[6], 10), parseInt(row[7], 10), parseInt(row[8], 10), parseInt(row[9], 10), parseFloat(row[10]), parseFloat(row[11]), parseFloat(row[12]), parseFloat(row[13]), parseFloat(row[14])) }) this.lineSubject.next(parsedListResults) }) } } class RcvData{ id: number; date: string; utcTime: string; refCharge: string; refDecharge: string; quantiteEnCours: string; quantiteHoraireReel: number; quantiteHoraireTheorique: number; quantitePosteReel: number; quantitePosteTheorique: number; trpHeureReel: number; trpPosteReel: number; trpObjectif: number; consoAir: number; consoElec: number; constructor( id: number, date: string, utcTime: string, refCharge: string, refDecharge: string, quantiteEnCours: string, quantiteHoraireReel: number, quantiteHoraireTheorique: number, quantitePosteReel: number, quantitePosteTheorique: number, trpHeureReel: number, trpPosteReel: number, trpObjectif: number, consoAir: number, consoElec: number) { this.id = id; this.date = date; this.utcTime = utcTime; this.refCharge = refCharge; this.refDecharge = refDecharge; this.quantiteEnCours = quantiteEnCours; this.quantiteHoraireReel = quantiteHoraireReel; this.quantiteHoraireTheorique = quantiteHoraireTheorique; this.quantitePosteReel = quantitePosteReel; this.quantitePosteTheorique = quantitePosteTheorique; this.trpHeureReel = trpHeureReel; this.trpPosteReel = trpPosteReel; this.trpObjectif = trpObjectif; this.consoAir = consoAir; this.consoElec = consoElec; } }
這里的主要變化是,現在我們不再擁有 static lines
ref,而是有一個BehaviourSubject
形式的“實時” ref,我們可以訂閱它,並在有任何更改時收到通知。
import { Component, OnInit } from '@angular/core'; import { LineService } from '../services/line.service'; import { ActivatedRoute } from '@angular/router'; import {async} from 'rxjs-compat/scheduler/async'; @Component({ selector: 'app-single-line', templateUrl: './single-line.component.html', styleUrls: ['./single-line.component.scss'] }) export class SingleLineComponent implements OnInit { name = 'Ligne...'; status = 'éteint'; date_jour = '2021-01-01'; heure_act = '00:00:00'; reference_charge = 'ST00S00'; reference_decharge = 'ST11S11'; quantite_produite = '1/1000'; quantite_h_reel = 0; quantite_h_th = 0; quantite_p_reel = 0; quantite_p_th = 0; trp_h_reel = 0; trp_p_reel = 0; trp_objectif = 0; conso_air = 0; conso_elec = 0; focusedData$ = combineLatest( this.lineService.lineSubject.pipe(filter(x => x.length > 0)), this.route.params.pipe(filter(x=>.,x.id). map(x => x,id)) ):pipe( map(([csvs, id]) => csvs[id]) ) constructor(private lineService: LineService, private route: ActivatedRoute) { } }
這里有趣的部分是我們正在組合存儲在 lineService 中創建的行為主題中的值和存儲在lineService
中的當前id
的 focusData focusData$
。 我們正在過濾所有無效值,然后,我們將 map 的 id 設置為相應的 csv。
從此時開始在您的模板中,您可以執行以下操作
<div *ngIf="focusedData$ | async"> <div> {{(focusedData$ | async).refCharge }} </div> <div> {{(focusedData$ | async).date }} </div> <div> {{(focusedData$ | async).utcTime }} </div> </div>
此偽代碼很可能會幫助您找到解決問題的方法,但無論如何,如果我站在您的立場上,我會考慮一種解決方案,即一次只調用一個 csv 並且在需要時,也可能不是最明智的在服務的構造函數中調用 http 調用的事情。
謝謝,謝謝,謝謝,它的工作原理。 多謝。
那不是“偽”代碼^^,我只更改了一件事。
this.route.params.pipe(filter(x=> !!x.id), map(x => x.id))
經過
this.route.params.pipe(filter(x=> !!x.id), map(x => x.id -1))
在正確的頁面中有正確的數據。 就這樣。
感謝您的回答,祝您有美好的一天
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.