初露锋芒 Angular6 入门项目 - 4 上

简介: 初露锋芒 Angular6 入门项目 - 4 上



本文目录

  • 六、改造组件
  • 1.添加历史记录组件
  • 2.添加和删除历史记录
  • 七、HTTP改造
  • 1.引入HTTP
  • 2.通过HTTP请求数据
  • 3.通过HTTP修改数据
  • 4.通过HTTP增加数据
  • 5.通过HTTP删除数据
  • 6.通过HTTP查找数据

本项目源码放在github


六、改造组件

从这里开始,我们要使用RxJS来改造组件和添加新功能了,让整个项目更加完善。

1.添加历史记录组件

  • 创建HistoryComponent组件
ng g component hostory

然后在app.component.html文件夹中添加组件:

<!-- app.component.html -->
<app-history></app-history>

2.添加增删改查功能

这里我们要开始做书本的增删改查功能,需要先创建一个HistoryService服务,方便我们实现这几个功能:

  • 创建HistoryService服务
ng g service history

然后在生成的ts文件中,增加addclear方法,add方法用来添加历史记录到history数组中,clear方法则是清空history数组:

// history.service.ts
export class HistoryService {
    history: string[] = [];
    add(history: string){
        this.history.push(history);
    }
    clear(){
        this.history = [];
    }
}
  • 使用HistoryService服务

在将这个服务,注入到BooksService中,并改造getBooks方法:

// books.service.ts
import { HistoryService } from './history.service';
constructor(
    private historyservice: HistoryService
) { }
getBooks(): void{
    this.historyservice.add('请求书本数据')
    this.booksservice.getBookList()
        .subscribe(books => this.books = books);
}

也可以用相同方法,在IndexComponent中添加访问首页书本列表的记录。

// index.component.ts
import { HistoryService } from '../history.service';
constructor(
    private booksservice: BooksService,
    private historyservice: HistoryService
) { }
getBooks(): void{
    this.historyservice.add('访问首页书本列表');
    this.booksservice.getBookList()
        .subscribe(books => this.books = books);
}

接下来,将我们的HistoryService注入到HistoryComponent中,然后才能将历史数据显示到页面上:

// history.component.ts
import { HistoryService } from '../history.service';
export class HistoryComponent implements OnInit {
    constructor(private historyservice: HistoryService) { }
    ngOnInit() {}
}
<!-- history.component.html -->
<div *ngIf="historyservice.history.length">
    <h2>操作历史:</h2>
    <div>
        <button class="clear"
        (click)="historyservice.clear()"
        >清除</button>
        <div *ngFor="let item of historyservice.history">{{item}}</div>
    </div>
</div>

代码解释

*ngIf="historyservice.history.length",是为了防止还没有拿到历史数据,导致后面的报错。

(click)="historyservice.clear()", 绑定我们服务中的clear事件,实现清除缓存。

*ngFor="let item of historyservice.history",将我们的历史数据渲染到页面上。

到了这一步,就能看到历史数据了,每次也换到首页,都会增加一条。

接下来,我们要在书本详情页也加上历史记录的统计,导入文件,注入服务,然后改造getBooks方法,实现历史记录的统计:

// detail.component.ts
import { HistoryService } from '../history.service';
export class DetailComponent implements OnInit {
    constructor(
        private route: ActivatedRoute,
        private location: Location,
        private booksservice: BooksService,
        private historyservice: HistoryService
    ) { }
    //...
    getBooks(id: number): void {
        this.books = this.booksservice.getBook(id);
        this.historyservice.add(`查看书本${this.books.title},id为${this.books.id}`);
        console.log(this.books)
    }
}

这时候就可以在历史记录中,看到这些操作的记录了,并且清除按钮也正常使用。


七、HTTP改造

原本我只想写到上一章,但是想到,我们实际开发中,哪有什么本地数据,基本上数据都是要从服务端去请求,所以这边也有必要引入这一张,模拟实际的HTTP请求。

1.引入HTTP

在这一章,我们使用Angular提供的 HttpClient 来添加一些数据持久化特性。

然后实现对书本数据进行获取,增加,修改,删除和查找功能。

HttpClient是Angular通过 HTTP 与远程服务器通讯的机制。

这里我们为了让HttpClient在整个应用全局使用,所以将HttpClient导入到根模块app.module.ts中,然后把它加入 @NgModule.imports 数组:

import { HttpClientModule } from '@angular/common/http';
@NgModule({
    //...
    imports: [
        BrowserModule,
        AppRoutingModule,
        HttpClientModule
    ],
    //...
})

这边我们使用 内存 Web API(In-memory Web API) 模拟出的远程数据服务器通讯。

注意: 这个内存 Web API 模块与 Angular 中的 HTTP 模块无关。

通过下面命令来安装:

npm install angular-in-memory-web-api --save

然后在app.module.ts中导入 HttpClientInMemoryWebApiModuleInMemoryDataService 类(后面创建):

// app.module.ts
import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService }  from './in-memory-data.service';
@NgModule({
    // ...
    imports: [
        // ...
        HttpClientInMemoryWebApiModule.forRoot(
        InMemoryDataService, {dataEncapsulation:false}
        )
    ],
    // ...
})
export class AppModule { }

知识点:

forRoot() 配置方法接受一个 InMemoryDataService 类(初期的内存数据库)作为参数。

然后我们要创建InMemoryDataService类:

ng g service InMemoryData

并将生成的in-memory-data.service.ts修改为:

// in-memory-data.service.ts
import { Injectable } from '@angular/core';
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { Books } from './books';
@Injectable({
  providedIn: 'root'
})
export class InMemoryDataService implements InMemoryDbService {
  createDb(){
    const books = [
      {
          id: 1, 
          url: 'https://img3.doubanio.com/view/subject/m/public/s29988481.jpg',
          title: '像火焰像灰烬',
          author: '程姬',
      },
      // 省略其他9条数据
    ];
    return {books};
  }
  constructor() { }
}

这里先总结InMemoryDbService所提供的RESTful API,后面都要用到:

例如如果urlapi/books,那么

  • 查询所有成员:以GET方法访问api/books
  • 查询某个成员:以GET方法访问api/books/id,比如id1,那么访问api/books/1
  • 更新某个成员:以PUT方法访问api/books/id
  • 删除某个成员:以DELETE方法访问api/books/id
  • 增加一个成员:以POST方法访问api/books

2.通过HTTP请求数据

现在要为接下来的网络请求做一些准备,先在books.service.ts中引入HTTP符号,然后注入HttpClient并改造:

// books.service.ts
import { HttpClient, HttpHeaders} from '@angular/common/http';
// ...
export class BooksService {
    constructor(
        private historyservice: HistoryService,
        private http: HttpClient
    ) { }
    private log(histories: string){
        this.historyservice.add(`正在执行:${histories}`)
    }
    private booksUrl = 'api/books'; // 提供一个API供调用
    // ...
}

这里我们还新增一个私有方法log和一个私有变量booksUrl

接下来我们要开始发起http请求数据,开始改造getBookList方法:

// books.service.ts
// ...
getBookList(): Observable<Books[]> {
    this.historyservice.add('请求书本数据')
    return this.http.get<Books[]>(this.booksUrl);
}
// ...

这里我们使用 http.get 替换了 of,其它没修改,但是应用仍然在正常工作,这是因为这两个函数都返回了 Observable<Hero[]>

实际开发中,我们还需要考虑到请求的错误处理,要捕获错误,我们就要使用 RxJS 的 catchError() 操作符来建立对 Observable 结果的处理管道(pipe)。

我们引入catchError 并改造原本getBookList方法:

// books.service.ts
getBookList(): Observable<Books[]> {
    this.historyservice.add('请求书本数据')
    return this.http.get<Books[]>(this.booksUrl).pipe(
        catchError(this.handleError<Books[]>('getHeroes', []))
    );
}
private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
        this.log(`${operation} 失败: ${error.message}`); // 发出错误通知
        return of(result as T); // 返回空结果避免程序出错
    };
}

知识点

.pipe() 方法用来扩展 Observable 的结果。

catchError() 操作符会拦截失败的 Observable。并把错误对象传给错误处理器,错误处理器会处理这个错误。

handleError() 错误处理函数做了两件事,发出错误通知和返回空结果避免程序出错。

这里还需要使用tap操作符改造getBookList方法,来窥探Observable数据流,它会查看Observable的值,然后我们使用log方法,记录一条历史记录。

tap 回调不会改变这些值本身。

// books.service.ts
getBookList(): Observable<Books[]> {
    return this.http.get<Books[]>(this.booksUrl)
        .pipe(
            tap( _ => this.log('请求书本数据')),
            catchError(this.handleError<Books[]>('getHeroes', []))
        );
}


目录
相关文章
|
2月前
1分钟入门angular动画效果animations,敲简单滴哟~~☺
1分钟入门angular动画效果animations,敲简单滴哟~~☺
|
2月前
|
C++
【angular】启动项目和路由配置
【angular】启动项目和路由配置
30 1
|
2月前
|
JavaScript UED 开发者
什么是 Angular 项目的 code split?
什么是 Angular 项目的 code split?
|
2月前
设置Open in Terminal快捷键Alt+Shift+Z,方便angular项目的各种命令输入(多任务状态下)
设置Open in Terminal快捷键Alt+Shift+Z,方便angular项目的各种命令输入(多任务状态下)
|
2月前
|
JavaScript 前端开发 开发工具
Angular 项目中一个 index.d.ts 文件的具体例子介绍
Angular 项目中一个 index.d.ts 文件的具体例子介绍
|
2月前
|
JavaScript 前端开发 开发者
Angular 项目里 tsconfig.schematics.json 文件的作用
Angular 项目里 tsconfig.schematics.json 文件的作用
|
2月前
|
应用服务中间件 nginx
Angular打包构建项目服务器运行runtime.js、polyfills.js、vendor.js报错net::ERR_ABORTED 404 (Not Found),build修改为相对路径./
Angular打包构建项目服务器运行runtime.js、polyfills.js、vendor.js报错net::ERR_ABORTED 404 (Not Found),build修改为相对路径./
|
2月前
|
存储 搜索推荐 API
通过项目中的实际例子,介绍 LocalStorage 在 Angular 开发中的使用场景
通过项目中的实际例子,介绍 LocalStorage 在 Angular 开发中的使用场景
|
2月前
|
存储 前端开发 API
浅谈 Angular 应用前端消息显示机制的一个实际需求
浅谈 Angular 应用前端消息显示机制的一个实际需求
|
2月前
|
JavaScript 前端开发 架构师
Angular进阶:理解RxJS在Angular应用中的高效运用
RxJS(Reactive Extensions for JavaScript)是JavaScript的一个响应式编程库,特别适用于处理异步数据流。
35 0