如何创建 Angular 服务?组件中注入服务的方法
服务一般用来放置可复用的代码。
如何创建 Angular 服务
在 Angular 中我们通过以下方式创建一个简单的服务:
export class BookService { getBooks() { return ['Angular', 'React', 'Vue']; } }
组件中注入服务">组件中注入服务
我们来创建一个新的组件 BookComponent,它用来显示书籍的信息:
// book.component.ts export class BookComponent implements OnInit { books: Array<{ id: number; name: string }>; ngOnInit() { this.books = [ { id: 11, name: 'Angular' }, { id: 12, name: 'React' }, { id: 13, name: 'Vue' } ]; } } // book.component.html
- ID: {{ book.id }} - Name: {{ book.name }}
在 BookComponent 组件中,我们在 ngOnInit 钩子中进行数据初始化,然后利用 ngFor 指令来显示书籍列表的信息。创建完 BookComponent 组件,我们来验证一下该组件的功能。
因为我是用 Angular CLI 脚手架创建的组件,所以已自动导入 AppModule,只需要记得在 app.component.html 中将内容更改为
目前我们实现的书籍信息是固定的,别忘了,在实际的开发场景中,一般需要从远程服务器获取相应的信息。但我们暂不考虑这个问题,假设另外一个组件也需要利用同样的书籍信息,那我们要怎么办,总不可能用复制粘贴~
接下来我们创建一个 BookService 服务,从而实现数据共享。
// book.service.ts export class BookService { books: Array<{ id: number; name: string}> = [ { id: 11, name: "Angular" }, { id: 12, name: "React" }, { id: 13, name: "Vue" } ]; getBooks() { return this.books; } }
在 BookService 服务中,我们定义了一个 books 属性和一个 getBooks() 方法:
books - 用于保存书籍的信息 getBooks() - 用于获取书籍的信息
创建完 BookService 服务后,就要使用它了!
组件中使用服务
主要分为三个步骤:
1)导入服务
// book.component.ts import { BookService } from '../book.service';
2)声明服务
方式一:
// book.component.ts @Component({ selector: 'app-book', ... providers: [BookService] })
方式二:
// app.module.ts @NgModule({ ... providers: [BookService], ... })
注意:不管哪种方式,记得一定要在文件头 import 进服务。
3)注入服务
// book.component.ts export class BookComponent implements OnInit { constructor(private bookService: BookService) {} }
问题1:可能会有人疑惑为什么去掉 private 会报错?
这里解释下,这是 TypeScript 的用法,跟 Java 类似,分别是 public、private、protected。
上述例子可以等价为:
// book.component.ts export class BookComponent implements OnInit { private bookService: BookService; constructor(bookService: BookService) { this.bookService = bookService; } }
问题2:为什么配置完 BookService,在 BookComponent 组件类中构造函数中还得进行类型声明?
因为在 @NgModule({...}) 或 @Component({...}) 的元数据中我们只是配置了 Provider 的相关信息,即告诉 Angular DI(依赖注入)系统,如何创建根据配置的 provider 信息,创建相应的依赖对象。而在 BookComponent 组件类中,我们通过构造注入的方式去告诉 Angular DI 系统,我们需要的依赖对象**类型。
|| 至此,我们只是勉强完成了服务,这样就OK了?当然不行!
下面来解决实际开发中遇到处理数据时如玩服务~
在这里模拟一个书籍列表,创建 book.json 并放置在 /assets/json/book.json 中:
{ "books": [ { "name": "Angular" }, { "name": "React" }, { "name": "Vue" } ] }
修改 book.service.ts :
// book.service.ts import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import 'rxjs/add/operator/toPromise'; @Injectable() export class BookService { constructor(private http: Http) {} private handleError(error: any): Promise { console.error('An error occurred' + error); } getBooks() { const url = '/assets/json/book.json'; return this.http.get(url).toPromise().then(res => res.json()).catch(this.handleError); } }
注:默认情况下,Angular 的Http服务返回一个 RxJS 的Observable对象。 我们可以通过 toPromise() 方法将其转为便捷的承诺Promise。 使用 toPromise() 方法时要引入:
import 'rxjs/add/operator/toPromise';
接下来使用这个 BookService 服务:
// book.component.ts import { Component, OnInit } from '@angular/core'; import { BookService } from '../book.service'; @Component({ selector: 'app-book', templateUrl: './book.component.html', styleUrls: ['./book.component.css'], providers: [BookService] }) export class BookComponent implements OnInit { constructor(private bookService: BookService) { }; books: any[]; ngOnInit() { this.bookService.getBooks().then(res => {this.books = res.books}; } }
常用服务
获取(get)数据:
get() { return this.http.get(url) .toPromise() .then(response => response.json() ) .catch(this.handleError); } private handleError(error: any): Promise { console.error('An error occurred', error); }
新建(post)数据:
private headers = new Headers({'Content-type': 'application/json'}); create() { return this.http .post(url, JSON.stringify(hero), {headers: this.headers}) .toPromise() .then(response => response.json()) .catch(this.handleError); }
更新(update)数据:
private headers = new Headers({'Content-type': 'application/json'}); update() { return this.http .put(url, JSON.stringify(hero), {headers: this.headers}) .toPromise() .then(response => response.json()) .catch(this.handleError); }
删除(delete)数据:
private headers = new Headers({'Content-type': 'application/json'}); delete() { return this.http .delete(url, {headers: this.headers}) .toPromise() .then(() => null) .catch(this.handleError); }
上一篇: 前端工程化及组件化开发学习
下一篇: 记一次ReactNative踩坑