angularJs service服务
什么是服务?
服务是一个广义的概念,它包括应用所需的任何值、函数或特性。狭义的服务是一个明确定义了用途的类。它应该做一些具体的事,并做好。
Angular 把组件和服务区分开,以提高模块性和复用性。 通过把组件中和视图有关的功能与其他类型的处理分离开,你可以让组件类更加精简、高效。
理想情况下,组件的工作只管用户体验,而不用顾及其它。 它应该提供用于数据绑定的属性和方法,以便作为视图(由模板渲染)和应用逻辑(通常包含一些模型的概念)的中介者。
组件应该把诸如从服务器获取数据、验证用户输入或直接往控制台中写日志等工作委托给各种服务。通过把各种处理任务定义到可注入的服务类中,你可以让它被任何组件使用。 通过在不同的环境中注入同一种服务的不同提供商,你还可以让你的应用更具适应性。
Angular 不会强迫你遵循这些原则。Angular 只会通过依赖注入来帮你更容易地将应用逻辑分解为服务,并让这些服务可用于各个组件中。
PS:上面这段说辞是官网的说辞,其实简单的理解就是:服务分离模板单独出来,可以供多个组件使用。常用于服务器获取数据、验证用户输入或直接往控制台中写日志等工作。服务一般放置可复用的代码。
创建一个服务
eg:管理书籍的服务(基本模板)
//book.service.ts
import { Injectable } from '@angular/core';
//建议每一个服务都加上@Injectable()装饰器
//当 TypeScript 看到@Injectable()装饰器时,就会记下本服务的元数据。 如果Angular 需要往这个服务中注入其它依赖,就会使用这些元数据
@Injectable()
export class BookService {
constructor() { }
//服务中的方法,获取书籍
getBooks() {}
}
我们以http方式从服务器获取数据,需将httpModule提前注入app.module.ts
// app.module.ts
import { HttpModule } from '@angular/http';
@NgModule({
...
imports: [
...
HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
书籍数据book.json
{
"books": [
{
"name": "HTML"
},
{
"name": "Javascript"
},
{
"name": "Angular"
}
]
}
import { Injectable } from "@angular/core";
import { Http } from "@angular/http";
import "rxjs/add/operator/toPromise";
@Injectable()
export class BookService {
//这儿也相当于是注入了一个http服务,是angular内置的服务
constructor(private http: Http) {}
//默认情况下,`Angular` 的`Http`服务返回一个 RxJS 的`Observable`对象。 我们可以通过`toPromise()`方法将其转为便捷的`Promise`。 使用toPromise()方法时要引入:
getBooks() {
const url = "/assets/books.json";
return this.http
.get(url)
.toPromise()
.then(res => res.json())
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error("An error occurred", error); // for demo purposes only
return Promise.reject(error.message || error);
}
}
注:默认情况下,
Angular
的Http
服务返回一个 RxJS 的Observable
对象。 我们可以通过toPromise()
方法将其转为便捷的Promise
。 使用toPromise()方法时要引入:
import 'rxjs/add/operator/toPromise';
接下来我们要使用这个BookService服务了:
// demo-service.service.ts
import { Component, OnInit } from '@angular/core';
import {BookService} from '../../service/book.service';
@Component({
...
providers: [BookService]
})
export class DemoServiceComponent implements OnInit {
books: any[];
constructor(private bookService: BookService) { }
ngOnInit() {
this.bookService.getBooks()
.then(res => {
this.books = res.books;
});
}
}
// demo-service.component.html
<li *ngFor="let book of books">{{book.name}}</li>
在上面的代码中,我们做了三步工作:
-
- 将
BookService
服务添加到@Component
组件的元数据底部添加providers
数组属性中。
- 将
-
- 将
BookService
注入到构造方法中,并定义了一个私有属性bookService
。
- 将
-
- 在
OnInit()
生命钩子函数中调用服务并获取书籍数据
- 在
注:
providers
数组告诉Angular
,当它创建新的DemoServiceComponent
组件时,也要创建一个BookService
的新实例。
尽量不要在构造方法中获取服务数据,要在生命钩子函数中调用。
常用服务:
获取(GET)数据:
get() {
return this.http.get(url)
.toPromise()
.then(response => response.json() )
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || 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);
}
写在最后
我之前学习了vuex,vuex是状态管理,有state,getter,mutation,action等。对组件共有的状态统一管理。而angular服务更多的是一些操作,相当于vuex的mutation,action的部分,只是操作的数据一般不在service内部,需向外部请求。一般用于服务器获取数据、验证用户输入或直接往控制台中写日志等