Javascript 在angular 2 beta版中,如何在服务中高效使用Http组件?
我正在尝试使用Angular 2-beta,我想使用Http组件。但这里有一个严重的问题: 我读了又读 我知道在Angular 2中(与Angular 1不同),Http组件不是返回承诺的服务。它返回一个名为可观察的。我们知道组件最好不要直接使用Http。有效的方法是创建一个负责使用Http的服务。但是怎么做?!在完成请求后,是否应返回承诺?(看)Javascript 在angular 2 beta版中,如何在服务中高效使用Http组件?,javascript,angular,Javascript,Angular,我正在尝试使用Angular 2-beta,我想使用Http组件。但这里有一个严重的问题: 我读了又读 我知道在Angular 2中(与Angular 1不同),Http组件不是返回承诺的服务。它返回一个名为可观察的。我们知道组件最好不要直接使用Http。有效的方法是创建一个负责使用Http的服务。但是怎么做?!在完成请求后,是否应返回承诺?(看) 这有意义吗 使用Angular 2可以实现服务。它们只是对应于如下所述的可注入类。在这种情况下,可以将此类注入到其他元素(如组件)中 import
这有意义吗 使用Angular 2可以实现服务。它们只是对应于如下所述的可注入类。在这种情况下,可以将此类注入到其他元素(如组件)中
import {Injectable} from 'angular2/core';
import {Http, Headers} from 'angular2/http';
import 'rxjs/add/operator/map';
@Injectable()
export class CompanyService {
constructor(http:Http) {
this.http = http;
}
}
在引导应用程序的主要组件时,可以在指定的条件下(使用其构造函数)在其中插入Http
对象:
import {bootstrap} from 'angular2/platform/browser'
import {HTTP_PROVIDERS} from 'angular2/http';
import {AppComponent} from './app.component'
bootstrap(AppComponent, [
HTTP_PROVIDERS
]);
然后可以将该服务注入组件,如下所述。不要忘记在组件的提供程序
列表中指定它
import { Component, View, Inject } from 'angular2/core';
import { CompanyService } from './company-service';
@Component({
selector: 'company-list',
providers: [ CompanyService ],
template: `
(...) `
})
export class CompanyList {
constructor(private service: CompanyService) {
this.service = service;
}
}
然后,您可以利用服务中的Http
对象实现一种方法,并返回与您的请求相对应的可观察对象:
@Injectable()
export class CompanyService {
constructor(http:Http) {
this.http = http;
}
getCompanies() {
return this.http.get('https://angular2.apispark.net/v1/companies/')
.map(res => res.json());
}
}
然后,组件可以调用此getcompanys
方法,并订阅可观察对象上的回调,以便在响应出现时通知以更新组件的状态(与Angular1中的Promissions相同):
编辑
正如他在评论中所建议的那样,async
管道也可以用于隐式订阅可观察对象。下面是使用它的方法。首先更新组件,将可观察对象放入要显示的属性中:
export class CompanyList implements OnInit {
public companies: Company[];
constructor(private service: CompanyService) {
this.service = service;
}
ngOnInit() {
this.companies = this.service.getCompanies();
}
}
然后在模板中使用异步管道:
@Component({
selector: 'company-list',
providers: [ CompanyService ],
template: `
<ul>
<li *ngFor="#company of companies | async">{{company.name}}</li>
</ul>
`
})
export class CompanyList implements OnInit {
(...)
}
@组件({
选择器:'公司列表',
提供者:[公司服务],
模板:`
- {{{company.name}
`
})
导出类CompanyList实现OnInit{
(...)
}
本文分为两个部分,也可以提供更多细节:
Thierry不需要将Http的get()方法返回的可观察内容转换为承诺。在大多数情况下,服务可以简单地返回可观察的 如果我们从服务器获取数组或基元类型(即字符串、数字、布尔值),我们可以通过直接在模板中使用返回的可观测值简化控制器逻辑,并使用。该管道将自动订阅可观察对象(它也与承诺一起工作),并将返回可观察对象发出的最新值。当发出新值时,管道将标记要检查的零部件以进行更改,因此视图将自动使用新值更新 如果我们从服务器获取对象,我不知道使用asyncPipe的任何方法,我们可以使用async pipe和安全导航操作符,如下所示:
{{(objectData$ | async)?.name}}
但这看起来很复杂,我们必须对每个要显示的对象属性重复这一点
相反,我建议我们subscribe()
订阅组件中的可观察对象,并将包含的对象存储到组件属性中。然后我们在模板中使用(?)或(如注释中提到的@Evan Plaice)NgIf。如果我们不使用安全导航操作符或NgIf,则当模板首次尝试渲染时将抛出错误,因为对象尚未填充值
请注意,下面的服务如何始终为每个get方法返回一个可观察值
服务台
从'angular2/core'导入{Injectable};
从'angular2/Http'导入{Http};
导入'rxjs/add/operator/map';//我们现在需要进口这个
@可注射()
导出类MyService{
构造函数(私有http:http){}
getArrayDataObservable(){
返回此值。_http.get('./data/array.json'))
.map(data=>data.json());
}
getPrimitiveDataObservable(){
返回此值。_http.get('./data/primitive.txt'))
.map(data=>data.text());//此处为note.text()
}
getObjectDataObservable(){
返回此值。_http.get('./data/object.json'))
.map(data=>data.json());
}
}
app.ts
从'angular2/core'导入{Component};
从“/MyService.service”导入{MyService};
从'angular2/HTTP'导入{HTTP_提供者};
@组成部分({
选择器:“我的应用程序”,
提供者:[HTTP_提供者,MyService],
模板:`
使用“|异步”的数组数据:
{{item}}
使用“|async”的基本数据:{{primitiveData$|async}
对象数据使用:{{objectData?.name}
使用NgIf的对象数据:{{objectData.name}`
})
导出类AppComponent{
构造函数(private _myService:myService){console.clear();}
恩戈尼尼特(){
this.arrayData$=this.\u myService.getArrayDataObservable();
this.primitiveData$=this.\u myService.getPrimitiveDataObservable();
这是._myService.getObjectDataObservable()
.subscribe(data=>this.objectData=data);
}
}
注意:我在服务方法名称中添加了“Observable”,例如,getArrayDataObservable()
,只是为了强调该方法返回一个Observable。通常情况下,您不会在名称中添加“可观察”
data/array.json
[ 1,2,3 ]
data/primitive.json
Greetings SO friends!
data/object.json
{ "name": "Mark" }
输出:
array data using '| async':
1
2
3
primitive data using '| async': Greetings SO friends!
object data using .?: Mark
object data using NgIf: Mark
使用
async
管道的一个缺点是组件中没有处理服务器错误的机制。我解释了如何在组件中捕获此类错误,但在这种情况下,我们始终需要使用subscribe()
。您可能希望使用异步管道而不是手动订阅。非常感谢@foox的评论!我更新了我的答案
array data using '| async':
1
2
3
primitive data using '| async': Greetings SO friends!
object data using .?: Mark
object data using NgIf: Mark