从 Angular 服务获取对象数组
Getting an object array from an Angular service
我是 Angular(以及 Javascript 的新手)。我写了一个 Angular 服务,其中 returns 一组用户。数据是从 HTTP 调用中检索的,其中 returns 数据采用 JSON 格式。当记录从 HTTP 调用返回的 JSON 数据时,我可以看到此调用成功并返回了正确的数据。我有一个调用服务以获取用户的组件和一个显示用户的 HTML 页面。我无法从服务获取数据到组件。我怀疑我错误地使用了 Observable。也许我也错误地使用了订阅。如果我在 ngInit 函数中注释掉 getUsers 调用并取消注释 getUsersMock 调用,一切正常,我看到 HTML 页面的列表框中显示的数据。我想将 JSON 数据转换为服务中用户的数组或列表,而不是从服务返回 JSON 并让组件转换它。
获取用户的 HTTP 调用返回的数据:
[
{
"firstName": "Jane",
"lastName": "Doe"
},
{
"firstName": "John",
"lastName": "Doe"
}
]
user.ts
export class User {
firstName: string;
lastName: string;
}
用户-service.ts
...
@Injectable
export class UserService {
private USERS: User[] = [
{
firstName: 'Jane',
lastName: 'Doe'
},
{
firstName: 'John',
lastName: 'Doe'
}
];
constructor (private http: Http) {}
getUsersMock(): User[] {
return this.USERS;
}
getUsers(): Observable<User[]> {
return Observable.create(observer => {
this.http.get('http://users.org').map(response => response.json();
})
}
...
user.component.ts
...
export class UserComponent implements OnInit {
users: User[] = {};
constructor(private userService: UserService) {}
ngOnInit(): void {
this.getUsers();
//this.getUsersMock();
}
getUsers(): void {
var userObservable = this.userService.getUsers();
this.userObservable.subscribe(users => { this.users = users });
}
getUsersMock(): void {
this.users = this.userService.getUsersMock();
}
}
...
user.component.html
...
<select disabled="disabled" name="Users" size="20">
<option *ngFor="let user of users">
{{user.firstName}}, {{user.lastName}}
</option>
</select>
...
!!!更新!!!
我一直在阅读 "heroes" 教程,但对我不起作用,所以我离开并尝试了其他东西。我已经按照英雄教程描述的方式重新实现了我的代码。但是,当我记录 this.users 的值时,它报告未定义。
这是我修改后的用户-service.ts
...
@Injectable
export class UserService {
private USERS: User[] = [
{
firstName: 'Jane',
lastName: 'Doe'
},
{
firstName: 'John',
lastName: 'Doe'
}
];
constructor (private http: Http) {}
getUsersMock(): User[] {
return this.USERS;
}
getUsers(): Promise<User[]> {
return this.http.get('http://users.org')
.toPromise()
.then(response => response.json().data as User[])
.catch(this.handleError);
}
...
这是我修改后的user.component.ts
...
export class UserComponent implements OnInit {
users: User[] = {};
constructor(private userService: UserService) {}
ngOnInit(): void {
this.getUsers();
//this.getUsersMock();
}
getUsers(): void {
this.userService.getUsers()
.then(users => this.users = users);
console.log('this.users=' + this.users); // logs undefined
}
getUsersMock(): void {
this.users = this.userService.getUsersMock();
}
}
...
!!!!!!!!!!!最终工作解决方案 !!!!!!!!!!!
这是最终工作解决方案的所有文件:
user.ts
export class User {
public firstName: string;
}
用户。service.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import { User } from './user';
@Injectable()
export class UserService {
// Returns this JSON data:
// [{"firstName":"Jane"},{"firstName":"John"}]
private URL = 'http://users.org';
constructor (private http: Http) {}
getUsers(): Observable<User[]> {
return this.http.get(this.URL)
.map((response:Response) => response.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
}
user.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { User } from './user';
import { UserService } from './user.service';
@Component({
moduleId: module.id,
selector: 'users-list',
template: `
<select size="5">
<option *ngFor="let user of users">{{user.firstName}}</option>
</select>
`
})
export class UserComponent implements OnInit{
users: User[];
title = 'List Users';
constructor(private userService: UserService) {}
getUsers(): void {
this.userService.getUsers()
.subscribe(
users => {
this.users = users;
console.log('this.users=' + this.users);
console.log('this.users.length=' + this.users.length);
console.log('this.users[0].firstName=' + this.users[0].firstName);
}, //Bind to view
err => {
// Log errors if any
console.log(err);
})
}
ngOnInit(): void {
this.getUsers();
}
}
看看你的代码:
getUsers(): Observable<User[]> {
return Observable.create(observer => {
this.http.get('http://users.org').map(response => response.json();
})
}
和来自 https://angular.io/docs/ts/latest/tutorial/toh-pt6.html 的代码
(顺便说一句,非常好的教程,你应该看看)
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data as Hero[])
.catch(this.handleError);
}
Angular2 中的 HttpService 已经 returns 一个 Observable,所以不需要像你在这里做的那样包装另一个 Observable:
return Observable.create(observer => {
this.http.get('http://users.org').map(response => response.json()
尝试按照我提供的 link 中的指南进行操作。仔细研究一下应该就好了。
---编辑----
首先,您在哪里记录 this.users 变量? JavaScript 不是那样工作的。您的变量未定义但没问题,因为代码执行顺序!
尝试这样做:
getUsers(): void {
this.userService.getUsers()
.then(users => {
this.users = users
console.log('this.users=' + this.users);
});
}
看看 console.log(...) 在哪里!
尝试退出 toPromise() 它似乎只适用于没有 RxJs 背景的人。
抓住另一个 link:https://scotch.io/tutorials/angular-2-http-requests-with-observables 使用 RxJs observables 再次构建您的服务。
我是 Angular(以及 Javascript 的新手)。我写了一个 Angular 服务,其中 returns 一组用户。数据是从 HTTP 调用中检索的,其中 returns 数据采用 JSON 格式。当记录从 HTTP 调用返回的 JSON 数据时,我可以看到此调用成功并返回了正确的数据。我有一个调用服务以获取用户的组件和一个显示用户的 HTML 页面。我无法从服务获取数据到组件。我怀疑我错误地使用了 Observable。也许我也错误地使用了订阅。如果我在 ngInit 函数中注释掉 getUsers 调用并取消注释 getUsersMock 调用,一切正常,我看到 HTML 页面的列表框中显示的数据。我想将 JSON 数据转换为服务中用户的数组或列表,而不是从服务返回 JSON 并让组件转换它。
获取用户的 HTTP 调用返回的数据:
[
{
"firstName": "Jane",
"lastName": "Doe"
},
{
"firstName": "John",
"lastName": "Doe"
}
]
user.ts
export class User {
firstName: string;
lastName: string;
}
用户-service.ts
...
@Injectable
export class UserService {
private USERS: User[] = [
{
firstName: 'Jane',
lastName: 'Doe'
},
{
firstName: 'John',
lastName: 'Doe'
}
];
constructor (private http: Http) {}
getUsersMock(): User[] {
return this.USERS;
}
getUsers(): Observable<User[]> {
return Observable.create(observer => {
this.http.get('http://users.org').map(response => response.json();
})
}
...
user.component.ts
...
export class UserComponent implements OnInit {
users: User[] = {};
constructor(private userService: UserService) {}
ngOnInit(): void {
this.getUsers();
//this.getUsersMock();
}
getUsers(): void {
var userObservable = this.userService.getUsers();
this.userObservable.subscribe(users => { this.users = users });
}
getUsersMock(): void {
this.users = this.userService.getUsersMock();
}
}
...
user.component.html
...
<select disabled="disabled" name="Users" size="20">
<option *ngFor="let user of users">
{{user.firstName}}, {{user.lastName}}
</option>
</select>
...
!!!更新!!!
我一直在阅读 "heroes" 教程,但对我不起作用,所以我离开并尝试了其他东西。我已经按照英雄教程描述的方式重新实现了我的代码。但是,当我记录 this.users 的值时,它报告未定义。
这是我修改后的用户-service.ts
...
@Injectable
export class UserService {
private USERS: User[] = [
{
firstName: 'Jane',
lastName: 'Doe'
},
{
firstName: 'John',
lastName: 'Doe'
}
];
constructor (private http: Http) {}
getUsersMock(): User[] {
return this.USERS;
}
getUsers(): Promise<User[]> {
return this.http.get('http://users.org')
.toPromise()
.then(response => response.json().data as User[])
.catch(this.handleError);
}
...
这是我修改后的user.component.ts
...
export class UserComponent implements OnInit {
users: User[] = {};
constructor(private userService: UserService) {}
ngOnInit(): void {
this.getUsers();
//this.getUsersMock();
}
getUsers(): void {
this.userService.getUsers()
.then(users => this.users = users);
console.log('this.users=' + this.users); // logs undefined
}
getUsersMock(): void {
this.users = this.userService.getUsersMock();
}
}
...
!!!!!!!!!!!最终工作解决方案 !!!!!!!!!!! 这是最终工作解决方案的所有文件:
user.ts
export class User {
public firstName: string;
}
用户。service.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import { User } from './user';
@Injectable()
export class UserService {
// Returns this JSON data:
// [{"firstName":"Jane"},{"firstName":"John"}]
private URL = 'http://users.org';
constructor (private http: Http) {}
getUsers(): Observable<User[]> {
return this.http.get(this.URL)
.map((response:Response) => response.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
}
user.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { User } from './user';
import { UserService } from './user.service';
@Component({
moduleId: module.id,
selector: 'users-list',
template: `
<select size="5">
<option *ngFor="let user of users">{{user.firstName}}</option>
</select>
`
})
export class UserComponent implements OnInit{
users: User[];
title = 'List Users';
constructor(private userService: UserService) {}
getUsers(): void {
this.userService.getUsers()
.subscribe(
users => {
this.users = users;
console.log('this.users=' + this.users);
console.log('this.users.length=' + this.users.length);
console.log('this.users[0].firstName=' + this.users[0].firstName);
}, //Bind to view
err => {
// Log errors if any
console.log(err);
})
}
ngOnInit(): void {
this.getUsers();
}
}
看看你的代码:
getUsers(): Observable<User[]> {
return Observable.create(observer => {
this.http.get('http://users.org').map(response => response.json();
})
}
和来自 https://angular.io/docs/ts/latest/tutorial/toh-pt6.html 的代码 (顺便说一句,非常好的教程,你应该看看)
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data as Hero[])
.catch(this.handleError);
}
Angular2 中的 HttpService 已经 returns 一个 Observable,所以不需要像你在这里做的那样包装另一个 Observable:
return Observable.create(observer => {
this.http.get('http://users.org').map(response => response.json()
尝试按照我提供的 link 中的指南进行操作。仔细研究一下应该就好了。
---编辑----
首先,您在哪里记录 this.users 变量? JavaScript 不是那样工作的。您的变量未定义但没问题,因为代码执行顺序!
尝试这样做:
getUsers(): void {
this.userService.getUsers()
.then(users => {
this.users = users
console.log('this.users=' + this.users);
});
}
看看 console.log(...) 在哪里!
尝试退出 toPromise() 它似乎只适用于没有 RxJs 背景的人。
抓住另一个 link:https://scotch.io/tutorials/angular-2-http-requests-with-observables 使用 RxJs observables 再次构建您的服务。