Javascript 在angular 2 beta版中,如何在服务中高效使用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-beta,我想使用Http组件。但这里有一个严重的问题:

我读了又读 我知道在Angular 2中(与Angular 1不同),Http组件不是返回承诺的服务。它返回一个名为可观察的。我们知道组件最好不要直接使用Http。有效的方法是创建一个负责使用Http的服务。但是怎么做?!在完成请求后,是否应返回承诺?(看)


这有意义吗

使用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