Angular2 将 JSON 数据添加到单页应用程序
Angular2 adding JSON data to single page app
我最近开始尝试使用 Angular 2,并且坚持尝试向服务添加 JSON 数据。我已经 运行 阅读了官方教程和有关 HTTP 请求的文档,但似乎无法正常工作。服务的基础代码如下-
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Address } from './models/address';
const AddressEndpoint = 'https://jsonplaceholder.typicode.com/users';
@Injectable()
export class AddressService {
constructor(private http: HttpClient) { }
getAll(): Observable<Address[]> {
throw new Error('NOT IMPLEMENTED');
}
get(id: number): Address {
throw new Error('NOT IMPLEMENTED');
}
insert(addr: Address) {
throw new Error('NOT IMPLEMENTED');
}
remove(id: number) {
throw new Error('NOT IMPLEMENTED');
}
如何在每个 class 方法中访问 AddressEndpoint 常量,以及如何指定我想为每个请求获取哪条数据?然后,我需要使用以下代码将其提供给地址模型,但对于如何将提取的数据推送到此处,我还是有点不清楚。
export class Address {
id: number;
name: string;
address: {
street?: string,
suite?: string,
city?: string,
zipcode?: string
};
}
我建议将您的端点地址保存在单独的文件中(以及其他常量),如下所示:
export const endPointAddress = "http://youraddress".
然后你可以导入这个常量并像往常一样使用。
在现实世界的应用程序中,您将创建 class,它将有两个字段 - 一个用于开发环境的端点,另一个 - 用于生产或阶段。
这有点难以回答,因为关于 JSON 的结构、数据的结构方式以及您希望使用 AddressService
中存根的每个方法检索的数据的信息很少。
访问公共 属性 的一个选项是简单地使用 class 属性,例如 readonly
,在 AddressService 上,您可以访问在任何 AddressService
class 方法中使用 this
的值:
@Injectable()
export class AddressService {
readonly AddressEndpoint = 'https://jsonplaceholder.typicode.com/users';
constructor(private http: HttpClient) { }
get(id: number): Observable<Address> {
return this.http.get(`${this.AddressEndpoint}/${id}`);
}
}
在将结果映射到 type/model 方面,例如您的 Address
,您可以 typecheck the response 和 HttpClient
如下:
get(id: number): Observable<Address> {
return this.http.get<Address>(`${this.AddressEndpoint}/${id}`);
}
否则,您可以根据需要利用 rjxs map
运算符将响应转换为 Address
type/model,然后再将其转换为 class subscribe()
:
get(id: number): Observable<Address> {
return this.http.get(`${this.AddressEndpoint}/${id}`).map(data => new Address(data['someProperty'], data['someOtherProperty']);
}
注意: 如果您使用 @angular/cli 并将使用 HttpClient
来执行类似 get()
到 JSON 文件位于 AddressService
旁边,您需要将该文件添加到 angular-cli.json
.
的 assets
数组 属性
希望对您有所帮助!
据我了解,您是在询问如何将 JSON 发送到您的 REST 端点以及如何将响应中的数据检索到您的模型对象中。如果是这种情况,请继续阅读 :)
这是 GET 请求的示例实现:
/**
* Generic method that sends an HTTP GET request at the configured serviceUrl
* @returns {Observable<T>} - contains the converted data extracted from the response
*/
public get<T>(url: string): Observable<T[]> {
return this.httpClient.get<MyResponse<T[]>>(url, {observe: 'response'})
.do(res => this.logResponse(res))
.filter(res => res.status === 200)
.map(res => res.body.data)
.catch((error: HttpErrorResponse) => this.handleError(error));
}
当调用这样的方法时 this.httpClient.get<MyResponse<T[]>>
,我们可以告诉 httpClient 我们期望响应的类型是 MyReponse<T[]>
。
MyResponse
是描述响应外观的模型,很像包装器:
/**
* Template class for the backend JSON response which looks like this:
* {
* "data": <DATA_FROM_BACKEND>
* }
*/
export class MyResponse<T> {
constructor(public data: T) {
}
}
<T[]>
是MyResponse包裹的数据对象的类型。在你的情况下,它会像这样 this.httpClient.get<MyResponse<Address[]>>
并且它会描述一个 JSON 看起来像这样的响应:
{
"data": [
{
"id": 1,
"name": "John Doe",
"address": {
"city": "NY",
"street": "Wall Street",
"suite": "string",
"zipcode": "007"
},
{
"id": 2,
"name": "John Doe2",
"address": {
"city": "NY",
"street": "Wall Street",
"suite": "string",
"zipcode": "007"
}
]
}
{observe: 'response'}
告诉 HttpClient
您想要观察响应以便对整个响应对象进行操作并执行以下操作:
.filter(res => res.status === 200)
.map(res => res.body.data)
.map(res => res.body.data)
这里我们将 data
属性 (MyResponse.data) 从 JSON 转换为类型 <T>
.
为了使其适应您的用例,您的服务中应该有这样的东西:
public get(url: string): Observable<Address[]> {
return this.httpClient.get<MyResponse<Address[]>>(url, {observe: 'response'})
.do(res => this.logResponse(res))
.filter(res => res.status === 200)
.map(res => res.body.data)
.catch((error: HttpErrorResponse) => this.handleError(error));
}
你会像这样在你的组件中使用它:
this.formService.get('/users').subscribe(address => {
console.log(address);
});
你的 URL 必须是这样的 /users
。您无需指定完整路径。
这里是一个 POST:
的例子
public insert(url: string, entity: Address): Observable<number> {
let headers: HttpHeaders = new HttpHeaders()
.set('Content-Type', 'application/json');
return this.httpClient.post<ImResponse<number>>(url, JSON.stringify(entity), {
headers: headers,
observe: 'response'
})
.do(res => this.logResponse(res))
.filter(response => response.status === 201)
.map(response => response.body.data)
.catch((error: HttpErrorResponse) => this.handleError(error));
}
并像这样使用它:
let entity: Address = new Address();
this.formService.insert('/users', entity).subscribe(id => {
console.log(id);
});
注意:以上代码改编自实际生产代码。我没有测试过,可能有错别字。
我希望这些示例也能帮助您实现其他方法。
我最近开始尝试使用 Angular 2,并且坚持尝试向服务添加 JSON 数据。我已经 运行 阅读了官方教程和有关 HTTP 请求的文档,但似乎无法正常工作。服务的基础代码如下-
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Address } from './models/address';
const AddressEndpoint = 'https://jsonplaceholder.typicode.com/users';
@Injectable()
export class AddressService {
constructor(private http: HttpClient) { }
getAll(): Observable<Address[]> {
throw new Error('NOT IMPLEMENTED');
}
get(id: number): Address {
throw new Error('NOT IMPLEMENTED');
}
insert(addr: Address) {
throw new Error('NOT IMPLEMENTED');
}
remove(id: number) {
throw new Error('NOT IMPLEMENTED');
}
如何在每个 class 方法中访问 AddressEndpoint 常量,以及如何指定我想为每个请求获取哪条数据?然后,我需要使用以下代码将其提供给地址模型,但对于如何将提取的数据推送到此处,我还是有点不清楚。
export class Address {
id: number;
name: string;
address: {
street?: string,
suite?: string,
city?: string,
zipcode?: string
};
}
我建议将您的端点地址保存在单独的文件中(以及其他常量),如下所示:
export const endPointAddress = "http://youraddress".
然后你可以导入这个常量并像往常一样使用。 在现实世界的应用程序中,您将创建 class,它将有两个字段 - 一个用于开发环境的端点,另一个 - 用于生产或阶段。
这有点难以回答,因为关于 JSON 的结构、数据的结构方式以及您希望使用 AddressService
中存根的每个方法检索的数据的信息很少。
访问公共 属性 的一个选项是简单地使用 class 属性,例如 readonly
,在 AddressService 上,您可以访问在任何 AddressService
class 方法中使用 this
的值:
@Injectable()
export class AddressService {
readonly AddressEndpoint = 'https://jsonplaceholder.typicode.com/users';
constructor(private http: HttpClient) { }
get(id: number): Observable<Address> {
return this.http.get(`${this.AddressEndpoint}/${id}`);
}
}
在将结果映射到 type/model 方面,例如您的 Address
,您可以 typecheck the response 和 HttpClient
如下:
get(id: number): Observable<Address> {
return this.http.get<Address>(`${this.AddressEndpoint}/${id}`);
}
否则,您可以根据需要利用 rjxs map
运算符将响应转换为 Address
type/model,然后再将其转换为 class subscribe()
:
get(id: number): Observable<Address> {
return this.http.get(`${this.AddressEndpoint}/${id}`).map(data => new Address(data['someProperty'], data['someOtherProperty']);
}
注意: 如果您使用 @angular/cli 并将使用 HttpClient
来执行类似 get()
到 JSON 文件位于 AddressService
旁边,您需要将该文件添加到 angular-cli.json
.
assets
数组 属性
希望对您有所帮助!
据我了解,您是在询问如何将 JSON 发送到您的 REST 端点以及如何将响应中的数据检索到您的模型对象中。如果是这种情况,请继续阅读 :)
这是 GET 请求的示例实现:
/**
* Generic method that sends an HTTP GET request at the configured serviceUrl
* @returns {Observable<T>} - contains the converted data extracted from the response
*/
public get<T>(url: string): Observable<T[]> {
return this.httpClient.get<MyResponse<T[]>>(url, {observe: 'response'})
.do(res => this.logResponse(res))
.filter(res => res.status === 200)
.map(res => res.body.data)
.catch((error: HttpErrorResponse) => this.handleError(error));
}
当调用这样的方法时 this.httpClient.get<MyResponse<T[]>>
,我们可以告诉 httpClient 我们期望响应的类型是 MyReponse<T[]>
。
MyResponse
是描述响应外观的模型,很像包装器:
/**
* Template class for the backend JSON response which looks like this:
* {
* "data": <DATA_FROM_BACKEND>
* }
*/
export class MyResponse<T> {
constructor(public data: T) {
}
}
<T[]>
是MyResponse包裹的数据对象的类型。在你的情况下,它会像这样 this.httpClient.get<MyResponse<Address[]>>
并且它会描述一个 JSON 看起来像这样的响应:
{
"data": [
{
"id": 1,
"name": "John Doe",
"address": {
"city": "NY",
"street": "Wall Street",
"suite": "string",
"zipcode": "007"
},
{
"id": 2,
"name": "John Doe2",
"address": {
"city": "NY",
"street": "Wall Street",
"suite": "string",
"zipcode": "007"
}
]
}
{observe: 'response'}
告诉 HttpClient
您想要观察响应以便对整个响应对象进行操作并执行以下操作:
.filter(res => res.status === 200)
.map(res => res.body.data)
.map(res => res.body.data)
这里我们将 data
属性 (MyResponse.data) 从 JSON 转换为类型 <T>
.
为了使其适应您的用例,您的服务中应该有这样的东西:
public get(url: string): Observable<Address[]> {
return this.httpClient.get<MyResponse<Address[]>>(url, {observe: 'response'})
.do(res => this.logResponse(res))
.filter(res => res.status === 200)
.map(res => res.body.data)
.catch((error: HttpErrorResponse) => this.handleError(error));
}
你会像这样在你的组件中使用它:
this.formService.get('/users').subscribe(address => {
console.log(address);
});
你的 URL 必须是这样的 /users
。您无需指定完整路径。
这里是一个 POST:
的例子public insert(url: string, entity: Address): Observable<number> {
let headers: HttpHeaders = new HttpHeaders()
.set('Content-Type', 'application/json');
return this.httpClient.post<ImResponse<number>>(url, JSON.stringify(entity), {
headers: headers,
observe: 'response'
})
.do(res => this.logResponse(res))
.filter(response => response.status === 201)
.map(response => response.body.data)
.catch((error: HttpErrorResponse) => this.handleError(error));
}
并像这样使用它:
let entity: Address = new Address();
this.formService.insert('/users', entity).subscribe(id => {
console.log(id);
});
注意:以上代码改编自实际生产代码。我没有测试过,可能有错别字。
我希望这些示例也能帮助您实现其他方法。