angular6之Http服务

本文详细介绍了在Angular框架中如何封装HTTP请求为服务,实现组件间前后端数据交互。通过具体示例,讲解了如何进行数据的创建、读取、更新和删除(CRUD)操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在angular中我们可以将http请求封装成服务,在组件中引入该服务,
就可以实现前后端的数据请求。
具体实现:
1、ng generate service app
在app根目录下生成app.service.ts的文件,里面基本配置项已经生成。
2、引入Injectable注入模块,同时引入http模块

import { Injectable } from '@angular/core’
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})

加上providedIn: ‘root’,自动将服务加入到跟模块的providers中,这样该服务就可以在应用中的任何地方使用
3、构造函数中声明http的私有属性,将httpClient注入到http中

constructor (
private $http: HttpClient
){}

httpParams类可以设置请求参数

具体设置:

let params = new HttpParams();

params=params.set(key, value);

httpHeader类用来设置请求头

具体设置:

let headers = new HttpHeaders().set("Content-Type", "application/json");

http的Request方法,执行请求并返回Observable对象(类似于promise,处理异步编程的解决方案),最后直接调用Observable.subscribe方法处理结果。

例如:

this.$http.request('get', url, {params: params, headers: headers});

request方法的传参官方说明,可以针对post,get等做统一封装。
在这里插入图片描述

深入

1.修改Hero的信息

当需要修改某一个hero的名字的时候,当点击后退的时候,之前的所做的改变的信息都会小时不在,在实际应用中,这些修改都应该是被保存的,需要将修改后的信息,传输给远端的服务器,进而的正真的修改这条数据。

在hero-detail的模版文件中,增加一个save按钮,并绑定一个点击事件save()。

<button (click)=“save()”>save

实现save()方法:使用heroService中的updateHero()(稍后添加)方法来保存对某一个hero信息修改,然后导航返回之前的一个视图。

save(): void {
   this.heroService.updateHero(this.hero)
     .subscribe(() => this.goBack());
 }

添加updateHero() 方法,在项目中,在进行更新操作的时候,一般情况下发送的是put请求,所以,在这里要调用http.put()方法,注:这里的http是HttpClient的实例化的一个对象,将进行的更改保存在远端的服务器上。

updateHero (hero: Hero): Observable<any> {
  return this.http.put(this.heroesUrl, hero, httpOptions).pipe(
    tap(_ => this.log(`updated hero id=${hero.id}`)),
    catchError(this.handleError<any>('updateHero'))
  );
}

HttpClient.put() 方法接受三个参数

URL 地址

要修改的数据(这里就是修改后的英雄)

选项

一般情况,对于一系列中的其中一个事物进行修改,这个时候,可能就需要一个能唯一标示出这个事物的一个参数,常常用的是这个事物的ID,在当前的这个demo中,就可以使用每个hero的id对每个hero进行区别,从而知道具体更新的是哪一个hero。但有时候,(少数情况下)有时会会利用put方法进行新建操作(偶尔使用,不推荐)。

关于参数中的选项:option

有时在传输过程中,需要一个增加一些有特殊意思的请求头,这个时候,就可以在option中使用,就是updateHero方法中的httpOptions

在这里httpOptions:(由于这个httpOptions基本不会再进行改动,所以,用常量const 定义)

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

此时,保存刷新浏览器,修改一个hero的name,然后点击save按钮,然后在返回的导航中,就可以看到hero修改后的新name。
2.新建一个hero

每一个应用的数据不可能仅仅只能修改,当有一个新的hero来到时,这个时候,就需要将新的hero信息增加到当前的hero列表中,我们需要一个输入框,让用户通过这个输入框输入新的hero的name,并在这个输入框的前面提示“Hero Name” ,使用户意识到这个输入的框的意思是输入hero的Name,增加完输入框以后,还需要增加一个按钮,在这个按钮上添加一个点击事件,当用户点击这个按钮的时候,开始获取用户在这个输入框输入的值,并将获取的值发送给远端的服务器,是远端的服务器的到这个新增的值,并添加至相应的数据库中。
a.添加input,button等控件。

<div>
  <label>Hero name:
    <input #heroName />
  </label>
  <button (click)="add(heroName.value); heroName.value=''">
    add
  </button>
</div>

b.给button上添加点击事件add(heroName.value),当点击这个button的时候,会触发清空之前填写的数据,当用户输入了数据以后,会将这个数据转换成Hero类似的对象(缺少hero的id属性)。当保存成功以后,会将这个hero的name放入(Array.push()方法)heroes的数组中进行展示。

add(name: string): void {
    name = name.trim();
    if (!name) {
      return;
    }
    this.heroService.addHero({name} as Hero)
      .subscribe(hero => {
        this.heroes.push(hero);
      });
  }

c.在httpservice中增加一个addHero()方法,利用http.post()方法向远端服务器进行传输数据(http是HttpClient创建的一个实例)。

addHero(hero: Hero): Observable<Hero> {
    return this.http.post<Hero>(this.heroesUrl, hero, httpOptions).pipe(
      tap((hero: Hero) => this.log(`added hero w/ id=${hero.id}`)),
      catchError(this.handleError<Hero>('addHero'))
    );
  }

问题:为何此时没有id属性?

在某个一系列的事物中,这种进行事物唯一标示的操作,是来自于远端的服务器后端的分配的,新建的时候,就需要新建的信息发送给后端就可以了,然后远端服务器那边会自动给当前的数据分配一个独一无二的标示(ID)

3.删除某一个Hero

当不要这个hero的时候,就需要将这个hero进行删除,将需要删除的hero传给远端的服务器。

在每一个hero

  • 标签里增加一个删除的按钮
  • <ul class="heroes">
      <li *ngFor="let hero of heroes">
        <a routerLink="/detail/{{hero.id}}">
          <span class="badge">{{hero.id}}</span> {{hero.name}}
        </a>
        <button class="delete" title="delete hero"
          (click)="delete(hero)">x</button>
      </li>
    </ul>
    

    使用一些CSS使这个删除按钮浮动在这个

  • 的右边。
  • .delete {
      position: relative;
      left: 194px;
      top: -32px;
      background-color: gray !important;
      color: white;
    }
    

    在类文件中实现删除button中的点击事件delete(hero)方法

    delete(hero: Hero): void {
      this.heroes = this.heroes.filter(h => h !== hero);
      this.heroService.deleteHero(hero).subscribe();
    }
    

    虽然这个组件把删除hero的逻辑委托给了 HeroService,但扔保留了更新它自己的hero列表的职责。 组件的 delete() 方法会在 HeroService 对服务器的操作成功之前,先从列表中移除要删除的hero。

    组件与 heroService.delete() 返回的 Observable 还完全没有关联。必须订阅它。

    在heroService中添加delete()方法

     deleteHero(hero: Hero | number): Observable<Hero> {
        const id = typeof hero === 'number' ? hero : hero.id;
        const url = `${this.heroesUrl}/${id}`;
     
        return this.http.delete<Hero>(url, httpOptions).pipe(
          tap(_ => this.log(`deleted hero id=${id}`)),
          catchError(this.handleError<Hero>('deleteHero'))
        );
      }
    

    注意

    它调用了 HttpClient.delete。
    
    URL 就是英雄的资源 URL 加上要删除的英雄的 id。
    
    你不用像 put 和 post 中那样发送任何数据。
    
    你仍要发送 httpOptions。
    

    保存,刷新浏览器,就可以点击删除按钮,删除需要删除的hero

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值