json 从 Angular 服务获取对象数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40256658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting an object array from an Angular service
提问by Nho Jotom
I am new to Angular (and Javascript for that matter). I've written an Angular service which returns an array of users. The data is retrieved from an HTTP call which returns the data in JSON format. When logging the JSON data returned from the HTTP call, I can see that this call is successful and the correct data is returned. I have a component which calls the service to get the users and an HTML page which displays the users. I cannot get the data from the service to the component. I suspect I am using the Observable incorrectly. Maybe I'm using subscribe incorrectly as well. If I comment out the getUsers call in the ngInit function and uncomment the getUsersMock call, everything works fine and I see the data displayed in the listbox in the HTML page. I'd like to convert the JSON data to an array or list of Users in the service, rather then returning JSON from the service and having the component convert it.
我是 Angular(以及 Javascript)的新手。我编写了一个返回用户数组的 Angular 服务。数据是从 HTTP 调用中检索的,该调用以 JSON 格式返回数据。在记录 HTTP 调用返回的 JSON 数据时,可以看到该调用成功并返回了正确的数据。我有一个调用服务来获取用户的组件和一个显示用户的 HTML 页面。我无法从服务获取数据到组件。我怀疑我错误地使用了 Observable。也许我也错误地使用了 subscribe 。如果我在 ngInit 函数中注释掉 getUsers 调用并取消对 getUsersMock 调用的注释,一切正常,我会看到 HTML 页面的列表框中显示的数据。一世'
Data returned from HTTP call to get users:
从 HTTP 调用返回的数据以获取用户:
[
{
"firstName": "Jane",
"lastName": "Doe"
},
{
"firstName": "John",
"lastName": "Doe"
}
]
user.ts
用户.ts
export class User {
firstName: string;
lastName: string;
}
user-service.ts
用户服务.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
用户组件.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
用户组件.html
...
<select disabled="disabled" name="Users" size="20">
<option *ngFor="let user of users">
{{user.firstName}}, {{user.lastName}}
</option>
</select>
...
!!! UPDATE !!!
!!!更新 !!!
I had been reading the "heroes" tutorial, but wasn't working for me so I went off and tried other things. I've re-implemented my code the way the heroes tutorial describes. However, when I log the value of this.users, it reports undefined.
我一直在阅读“英雄”教程,但对我不起作用,所以我去尝试其他东西。我已经按照英雄教程描述的方式重新实现了我的代码。但是,当我记录 this.users 的值时,它报告未定义。
Here is my revised user-service.ts
这是我修改后的 user-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);
}
...
Here is my revised user.component.ts
这是我修改后的 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();
}
}
...
!!!!!!!!!! FINAL WORKING SOLUTION !!!!!!!!!! This is all the files for the final working solution:
!!!!!!!!!!!! 最终的工作解决方案 !!!!!!!!!!!! 这是最终工作解决方案的所有文件:
user.ts
用户.ts
export class User {
public firstName: string;
}
user.service.ts
用户服务.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
用户组件.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();
}
}
采纳答案by jmachnik
Take a look at your code :
看看你的代码:
getUsers(): Observable<User[]> {
return Observable.create(observer => {
this.http.get('http://users.org').map(response => response.json();
})
}
and code from https://angular.io/docs/ts/latest/tutorial/toh-pt6.html(BTW. really good tutorial, you should check it out)
和来自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);
}
The HttpService inside Angular2 already returns an observable, sou don't need to wrap another Observable around like you did here:
Angular2 中的 HttpService 已经返回了一个 observable,所以你不需要像你在这里做的那样包装另一个 Observable:
return Observable.create(observer => {
this.http.get('http://users.org').map(response => response.json()
Try to follow the guide in link that I provided. You should be just fine when you study it carefully.
尝试按照我提供的链接中的指南进行操作。仔细研究应该没问题。
---EDIT----
- -编辑 - -
First of all WHERE you log the this.users variable? JavaScript isn't working that way. Your variable is undefined and it's fine, becuase of the code execution order!
首先你在哪里记录 this.users 变量?JavaScript 不是这样工作的。您的变量未定义,这很好,因为代码执行顺序!
Try to do it like this:
尝试这样做:
getUsers(): void {
this.userService.getUsers()
.then(users => {
this.users = users
console.log('this.users=' + this.users);
});
}
See where the console.log(...) is!
看看 console.log(...) 在哪里!
Try to resign from toPromise() it's seems to be just for ppl with no RxJs background.
尝试从 toPromise() 辞职,这似乎只适用于没有 RxJs 背景的人。
Catch another link: https://scotch.io/tutorials/angular-2-http-requests-with-observablesBuild your service once again with RxJs observables.
获取另一个链接:https: //scotch.io/tutorials/angular-2-http-requests-with-observables 使用 RxJs observables 再次构建您的服务。

