所以,我正在开展一个有角度的项目。我正在通过HTTP调用获取数据。
为了验证我做得对,我通常会在控制台上打印出来。当我尝试使用console.log()打印我的结果时,它只适用于我的方法中的对象。当我离开方法的范围时,console.log()不再起作用并打印出没有值的数组。我想我以错误的方式理解闭包。
无论如何,我真正的问题是我从JSON文件中获取数据并将它们转换为两个单独的数组,然后我尝试合并这两个数组。
这是我正在使用的服务:
import { Http } from '@angular/http/';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
@Injectable()
export class ManagersService {
list$;
contacts$: Array<any>;
items$;
nameDatabase: { name: string, id: number }[] = [] ;
emailDatabase = [];
managersList;
// tslint:disable-next-line:max-line-length
private url = '';
//I am hidden the URL, because it contains private data,
but it is a complex nested JSON object
constructor(private http: Http) {
}
getList() {
return this.http.get(this.url)
.map(response => response.json());
}
getManagersNames() {
this.getList()
.subscribe(list => {
this.list$ = list.data;
//console.log(this.list$);
for ( const l of this.list$) {
const managerName = l.attributes.name;
const managerId = parseInt(l.id);
const manager = { name: managerName, id: managerId };
this.nameDatabase.push(manager);
}
});
const x = this.nameDatabase;
return x;
}
checkId() {
this.getList()
.subscribe(list => {
this.contacts$ = list.included;
console.log(this.contacts$);
for ( const c of this.contacts$) {
const managerId = parseInt(c.id) - 1;
return managerId;
}
});
}
getManagersContacts() {
this.getList()
.subscribe(list => {
this.contacts$ = list.included;
// console.log(this.contacts$);
for ( const c of this.contacts$) {
if (c.attributes.email) {
const managerEmail = c.attributes.email;
const managerId = parseInt(c.id) - 1;
const manager = { email: managerEmail, id: managerId };
this.emailDatabase.push(manager);
} else {
const managerName = c.attributes.name;
const managerId = parseInt(c.id);
const manager = { name: managerName, id: managerId };
this.nameDatabase.push(manager);
}
}
});
const y = this.emailDatabase;
return y;
}
}
这是我正在使用的组件:
import { ManagersService } from './../services/managers.service';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-list-items',
templateUrl: './list-items.component.html',
styleUrls: ['./list-items.component.css']
})
export class ListItemsComponent implements OnInit {
// tslint:disable-next-line:max-line-length
constructor(private service: ManagersService) {
}
ngOnInit() {
const x = this.service.getManagersContacts();
console.log(x);
const y = this.service.getManagersNames();
console.log(y);
const hash = new Map();
x.concat(y).forEach(function(obj) {
hash.set(obj.id, Object.assign(hash.get(obj.id) || {}, obj));
});
const finalDatabase = Array.from(hash.values());
console.log(finalDatabase);
return finalDatabase;
}
}
最后,我的app.module.ts:
import { ManagersService } from './services/managers.service';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { ListItemsComponent } from './list-items/list-items.component';
import { SearchListComponent } from './search-list/search-list.component';
import { DropDownComponent } from './drop-down/drop-down.component';
@NgModule({
declarations: [
AppComponent,
ListItemsComponent,
SearchListComponent,
DropDownComponent
],
imports: [
BrowserModule,
HttpModule
],
providers: [
ManagersService
],
bootstrap: [AppComponent]
})
export class AppModule { }
我不确定试图回答这个问题,因为没有代码的plunker或stackblitz ......我将获得一个完全正确的类型代码示例的可能性很小。但希望这会让你知道需要做些什么。
首先,建议的经验法则是尽可能使用subscribe
尽可能靠近UI。这样,您就可以获得数据检索何时完成的通知,并可以根据需要使用该数据。
其次,要将Http调用中的数据重新格式化/转换为组件所需的格式,请在服务中使用.map
而不是.subscribe
。
服务
该服务将看起来像这样:
注意:未检查或验证语法!
getManagersContacts() {
this.getList().map(list => {
this.contacts$ = list.included;
// console.log(this.contacts$);
for ( const c of this.contacts$) {
if (c.attributes.email) {
const managerEmail = c.attributes.email;
const managerId = parseInt(c.id) - 1;
const manager = { email: managerEmail, id: managerId };
this.emailDatabase.push(manager);
} else {
const managerName = c.attributes.name;
const managerId = parseInt(c.id);
const manager = { name: managerName, id: managerId };
this.nameDatabase.push(manager);
}
}
});
return this.nameDatabase;
}
零件
该组件看起来像这样:
ngOnInit() {
const x = this.service.getManagersContacts().subscribe(names => {
// the data is retrieved at this point, so add any code here
// inside the subscribe
console.log(names);
})
// your other code
}