我已经与angularjs合作了一段时间,并且开始使用Angular(angular.io),但是我在理解Observables时遇到了麻烦(这是我的第一个应用程序。)
我有一个HTTP响应,需要将其由D3.js转换为D3.hierarchy,然后在of
(Rentabilidade.service.ts)中使用getResumo$()
返回一个空的Observable
此空的Observable将在组件(resumo.component.ts)中进行订阅。
在服务中,因为我需要转换数据,所以我订阅了Observable来操纵数据并更新此空的Observable。
但是组件中的console.log(d)
从未更新。仅在我的控制台中打印undefined
。
我在做什么错了?
P.S:如果我在服务中插入console.log(this.hierarchy$)
,则数据已更新,但没有传播到组件。
Rentabilidade.service.ts
import { Injectable } from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http'
import { Observable, Observer, of, from} from 'rxjs';
import { catchError, map, tap, filter } from 'rxjs/operators';
import * as d3 from "d3";
@Injectable({
providedIn: 'root'
})
export class RentabilidadeService {
private f_rntb_agg_rsmo = 'http://localhost/api/index.php/bco_dav_dm/f_rntb_agg_rsmo';
private hierarchy$: Observable<any>;
constructor(private http: HttpClient) {
}
getResumo$(): Observable<any> {
this.http.get(this.f_rntb_agg_rsmo)
.pipe(
catchError(this.handleError('getResumo',[]))
)
.subscribe(d => {
let nest = d3.nest()
.key(k => 'root')
.key(k => k.servico)
.key(k => k.produto_comercial)
.key(k => k.canal)
.key(k => k.ddd)
.key(k => k.nome_rede)
.entries(d);
let hierarchy = d3.hierarchy(nest[0], h => h.values)
hierarchy.eachAfter(x=> {x.contribuicao = x.sum(y=>y.contribuicao_mes_atul).value;
x.contribuicao_mom = x.sum(y=>y.contribuicao_mes_atul - y.contribuicao_mes_antr).value;
x.contribuicao_yoy = x.sum(y=>y.contribuicao_mes_atul - y.contribuicao_ano_antr).value;
});
this.hierarchy$ = hierarchy;
}
)
return Observable.create(observer => observer.next(this.hierarchy$));
}
private handleError(operation = 'nao informado', result?: any) {
return (error: any): Observable<any> => {
console.error(error);
return of(result);
}
}
}
resumo.component.ts
import { Component, OnInit } from '@angular/core';
import { RentabilidadeService } from '../rentabilidade.service';
@Component({
selector: 'rentabilidade-resumo',
templateUrl: './resumo.component.html',
styleUrls: ['./resumo.component.css']
})
export class ResumoComponent implements OnInit {
resumo = [];
constructor(private rentabilidadeService: RentabilidadeService) {}
ngOnInit() {
this.rentabilidadeService.getResumo$()
.subscribe(d => {this.resumo = d; console.log(d)});
}
}
答案 0 :(得分:0)
在您的getResumo$
方法http.get()
上是一个异步调用,函数的返回调用将等到它从服务器获得响应后再等待。
如果您要处理来自http请求的数据,可以尝试此方法。
返回http请求方法,然后在组件上编写数据嵌套函数。如果选择此方法,则如果您有多个依赖于此类型数据操作的组件,则可能必须在应用程序的多个位置编写相同的方法(除非使用服务)。 示例:
getResumo$(): Observable<any> {
retun this.http.get(this.f_rntb_agg_rsmo);
}
然后在您的component.ts
文件上订阅响应。
或者您可以将整个getResumo$()
包装在Observable.create
中
例如:
getResumo$(): Observable<any> {
return Observable.create(observer => {
this.http.get(this.f_rntb_agg_rsmo)
.pipe(catchError(this.handleError('getResumo',[])))
.subscribe(d => {
let nest = d3.nest()
.key(k => 'root')
.key(k => k.servico)
.key(k => k.produto_comercial)
.key(k => k.canal)
.key(k => k.ddd)
.key(k => k.nome_rede)
.entries(d);
let hierarchy = d3.hierarchy(nest[0], h => h.values)
hierarchy.eachAfter(x=> {x.contribuicao =
x.sum(y=>y.contribuicao_mes_atul).value;
x.contribuicao_mom = x.sum(y=>y.contribuicao_mes_atul -
y.contribuicao_mes_antr).value;
x.contribuicao_yoy = x.sum(y=>y.contribuicao_mes_atul -
y.contribuicao_ano_antr).value;
});
this.hierarchy$ = hierarchy;
observer.next(this.hierarchy$));
});
}
}