91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解Angular服務

發布時間:2021-11-26 17:21:57 來源:億速云 閱讀:209 作者:柒染 欄目:開發技術

本篇文章為大家展示了如何理解Angular服務,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

為什么需要服務

組件不應該直接獲取或保存數據,它們不應該了解是否在展示假數據。 它們應該聚焦于展示數據,而把數據訪問的職責委托給某個服務。

你將創建一個 HeroService,應用中的所有類都可以使用它來獲取英雄列表。 不要使用 new 來創建此服務,而要依靠 Angular 的依賴注入機制把它注入到 HeroesComponent 的構造函數中。

服務是在多個“互相不知道”的類之間共享信息的好辦法。 你將創建一個 MessageService,并且把它注入到兩個地方:

  1. HeroService 中,它會使用該服務發送消息。

  2. MessagesComponent 中,它會顯示其中的消息。

創建 HeroService

使用 Angular CLI 創建一個名叫 hero 的服務。

ng generate service hero

該命令會在src/app/hero.service.ts中生成HeroService類的骨架。HeroService類的代碼如下:

src/app/hero.service.ts (new service)

import { Injectable } from '@angular/core';
 
@Injectable({
  providedIn: 'root',
})
export class HeroService {
 
  constructor() { }
 
}

@Injectable() 服務

注意,這個新的服務導入了 Angular 的 Injectable 符號,并且給這個服務類添加了 @Injectable() 裝飾器。 它把這個類標記為依賴注入系統的參與者之一。HeroService 類將會提供一個可注入的服務,并且它還可以擁有自己的待注入的依賴。 目前它還沒有依賴,但是很快就會有了。

@Injectable() 裝飾器會接受該服務的元數據對象,就像 @Component() 對組件類的作用一樣。

獲取英雄數據

HeroService 可以從任何地方獲取數據:Web 服務、本地存儲(LocalStorage)或一個模擬的數據源。

從組件中移除數據訪問邏輯,意味著將來任何時候你都可以改變目前的實現方式,而不用改動任何組件。 這些組件不需要了解該服務的內部實現。

這節課中的實現仍然會提供模擬的英雄列表

導入 Hero 和 HEROES

import { Hero } from './hero';
import { HEROES } from './mock-heroes';

添加一個 getHeroes 方法,讓它返回模擬的英雄列表

getHeroes(): Hero[] {
  return HEROES;
}

提供(provide) HeroService

在要求 Angular 把 HeroService 注入到 HeroesComponent 之前,你必須先把這個服務提供給依賴注入系統。稍后你就要這么做。 你可以通過注冊提供商來做到這一點。提供商用來創建和交付服務,在這個例子中,它會對 HeroService 類進行實例化,以提供該服務。

現在,你需要確保 HeroService 已經作為該服務的提供商進行過注冊。 你要用一個注入器注冊它。注入器就是一個對象,負責在需要時選取和注入該提供商。

默認情況下,Angular CLI 命令 ng generate service 會通過給 @Injectable 裝飾器添加元數據的形式,用根注入器將你的服務注冊成為提供商。

如果你看看 HeroService 緊前面的 @Injectable() 語句定義,就會發現 providedIn 元數據的值是 'root':

@Injectable({
  providedIn: 'root',
})
@

Injectable

({
  providedIn: 'root',})

當你在頂層提供該服務時,Angular 就會為 HeroService 創建一個單一的、共享的實例,并把它注入到任何想要它的類上。 在 @Injectable 元數據中注冊該提供商,還能允許 Angular 通過移除那些完全沒有用過的服務來進行優化。

要了解關于提供商的更多知識,參見提供商部分。 要了解關于注入器的更多知識,參見依賴注入指南。

現在 HeroService 已經準備好插入到 HeroesComponent 中了。

這是一個過渡性的代碼范例,它將會允許你提供并使用 HeroService。此刻的代碼和最終代碼相差很大。

修改 HeroesComponent

打開 HeroesComponent 類文件。

刪除 HEROES 的導入語句,因為你以后不會再用它了。 轉而導入 HeroService

src/app/heroes/heroes.component.ts (import HeroService)

import { HeroService } from '../hero.service';

把 heroes 屬性的定義改為一句簡單的聲明。

heroes: Hero[];

注入 HeroService

往構造函數中添加一個私有的 heroService,其類型為 HeroService

constructor(private heroService: HeroService) { }

這個參數同時做了兩件事:1. 聲明了一個私有 heroService 屬性,2. 把它標記為一個 HeroService 的注入點。

當 Angular 創建 HeroesComponent 時,依賴注入系統就會把這個 heroService 參數設置為 HeroService 的單例對象。

添加 getHeroes()

創建一個函數,以從服務中獲取這些英雄數據。

getHeroes(): void {
  this.heroes = this.heroService.getHeroes();
}

在 ngOnInit 中調用它

你固然可以在構造函數中調用 getHeroes(),但那不是最佳實踐。

讓構造函數保持簡單,只做初始化操作,比如把構造函數的參數賦值給屬性。 構造函數不應該做任何事。 它當然不應該調用某個函數來向遠端服務(比如真實的數據服務)發起 HTTP 請求。

而是選擇在 ngOnInit 生命周期鉤子中調用 getHeroes(),之后交由 Angular 處理,它會在構造出 HeroesComponent 的實例之后的某個合適的時機調用 ngOnInit。

ngOnInit() {
  this.getHeroes();
}

查看運行效果

刷新瀏覽器,該應用仍運行的一如既往。 顯示英雄列表,并且當你點擊某個英雄的名字時顯示出英雄詳情視圖。

可觀察(Observable)的數據

HeroService.getHeroes() 的函數簽名是同步的,它所隱含的假設是 HeroService 總是能同步獲取英雄列表數據。 而 HeroesComponent 也同樣假設能同步取到 getHeroes() 的結果。

this.heroes = this.heroService.getHeroes();

這在真實的應用中幾乎是不可能的。 現在能這么做,只是因為目前該服務返回的是模擬數據。 不過很快,該應用就要從遠端服務器獲取英雄數據了,而那天生就是異步操作。

HeroService 必須等服務器給出響應, 而 getHeroes() 不能立即返回英雄數據, 瀏覽器也不會在該服務等待期間停止響應。

HeroService.getHeroes() 必須具有某種形式的異步函數簽名

它可以使用回調函數,可以返回 Promise(承諾),也可以返回 Observable(可觀察對象)。

這節課,HeroService.getHeroes() 將會返回 Observable,因為它最終會使用 Angular 的 HttpClient.get 方法來獲取英雄數據,而 HttpClient.get() 會返回 Observable

可觀察對象版本的 HeroService

Observable 是 RxJS 庫中的一個關鍵類。

在稍后的 HTTP 教程中,你就會知道 Angular HttpClient 的方法會返回 RxJS 的 Observable。 這節課,你將使用 RxJS 的 of() 函數來模擬從服務器返回數據。

打開 HeroService 文件,并從 RxJS 中導入 Observable 和 of 符號。

src/app/hero.service.ts (Observable imports)

import { Observable, of } from 'rxjs';

把 getHeroes 方法改成這樣:

getHeroes(): Observable<Hero[]> {
  return of(HEROES);
}

of(HEROES)會返回一個Observable<Hero[]>,它會發出單個值,這個值就是這些模擬英雄的數組。

在 HTTP 教程中,你將會調用 HttpClient.get<Hero[]>() 它也同樣返回一個 Observable<Hero[]>,它也會發出單個值,這個值就是來自 HTTP 響應體中的英雄數組。

在 HeroesComponent 中訂閱

HeroService.getHeroes 方法之前返回一個 Hero[], 現在它返回的是 Observable<Hero[]>

你必須在 HeroesComponent 中也向本服務中的這種形式看齊。

找到 getHeroes 方法,并且把它替換為如下代碼(和前一個版本對比顯示):

heroes.component.ts (Observable)

getHeroes(): void {
  this.heroService.getHeroes()
      .subscribe(heroes => this.heroes = heroes);
}

heroes.component.ts (Original)

getHeroes(): void {
  this.heroes = this.heroService.getHeroes();
}

Observable.subscribe() 是關鍵的差異點。

上一個版本把英雄的數組賦值給了該組件的 heroes 屬性。 這種賦值是同步的,這里包含的假設是服務器能立即返回英雄數組或者瀏覽器能在等待服務器響應時凍結界面。

當 HeroService 真的向遠端服務器發起請求時,這種方式就行不通了。

新的版本等待 Observable 發出這個英雄數組,這可能立即發生,也可能會在幾分鐘之后。 然后,subscribe 函數把這個英雄數組傳給這個回調函數,該函數把英雄數組賦值給組件的 heroes屬性。

使用這種異步方式,當 HeroService 從遠端服務器獲取英雄數據時,就可以工作了

顯示消息

在這一節,你將

  • 添加一個 MessagesComponent,它在屏幕的底部顯示應用中的消息。

  • 創建一個可注入的、全應用級別的 MessageService,用于發送要顯示的消息。

  • 把 MessageService 注入到 HeroService 中。

  • 當 HeroService 成功獲取了英雄數據時顯示一條消息。

創建 MessagesComponent

使用 CLI 創建 MessagesComponent

ng generate component messages

CLI 在 src/app/messages 中創建了組件文件,并且把 MessagesComponent 聲明在了 AppModule 中。

修改 AppComponent 的模板來顯示所生成的 MessagesComponent

/src/app/app.component.html

<h2>{{title}}</h2>
<app-heroes></app-heroes>
<app-messages></app-messages>

你可以在頁面的底部看到來自的 MessagesComponent 的默認內容。

創建 MessageService

使用 CLI 在 src/app 中創建 MessageService

ng generate service message

打開MessageService,并把它的內容改成這樣:

/src/app/message.service.ts

import { Injectable } from '@angular/core';
 
@Injectable({
  providedIn: 'root',
})
export class MessageService {
  messages: string[] = [];
 
  add(message: string) {
    this.messages.push(message);
  }
 
  clear() {
    this.messages = [];
  }
}

該服務對外暴露了它的 messages 緩存,以及兩個方法:add() 方法往緩存中添加一條消息,clear() 方法用于清空緩存。

把它注入到 HeroService 中

重新打開 HeroService,并且導入 MessageService

/src/app/hero.service.ts (import MessageService)

import { MessageService } from './message.service';

修改這個構造函數,添加一個私有的 messageService 屬性參數。 Angular 將會在創建 HeroService 時把 MessageService 的單例注入到這個屬性中。

constructor(private messageService: MessageService) { }

這是一個典型的“服務中的服務”場景: 你把 MessageService 注入到了 HeroService 中,而 HeroService 又被注入到了 HeroesComponent 中。

從 HeroService 中發送一條消息

修改 getHeroes 方法,在獲取到英雄數組時發送一條消息。

getHeroes(): Observable<Hero[]> {
  // TODO: send the message _after_ fetching the heroes
  this.messageService.add('HeroService: fetched heroes');
  return of(HEROES);
}

從 HeroService 中顯示消息

MessagesComponent 可以顯示所有消息, 包括當 HeroService 獲取到英雄數據時發送的那條。

打開 MessagesComponent,并且導入 MessageService

/src/app/messages/messages.component.ts (import MessageService)

import { MessageService } from '../message.service';

修改構造函數,添加一個 public 的 messageService 屬性。 Angular 將會在創建 MessagesComponent 的實例時 把 MessageService 的實例注入到這個屬性中。

constructor(public messageService: MessageService) {}

這個messageService屬性必須是公共屬性,因為你將會在模板中綁定到它。

Angular 只會綁定到組件的公共屬性。

綁定到 MessageService

把 CLI 生成的 MessagesComponent 的模板改成這樣:

src/app/messages/messages.component.html

<div *ngIf="messageService.messages.length">
 
  <h3>Messages</h3>
  <button class="clear"
          (click)="messageService.clear()">clear</button>
  <div *ngFor='let message of messageService.messages'> {{message}} </div>
 
</div>

這個模板直接綁定到了組件的 messageService 屬性上。

  • *ngIf 只有在有消息時才會顯示消息區。

  • *ngFor 用來在一系列 <div> 元素中展示消息列表。

  • Angular 的事件綁定把按鈕的 click 事件綁定到了 MessageService.clear()

當你把 最終代碼 某一頁的內容添加到 messages.component.css 中時,這些消息會變得好看一些。

刷新瀏覽器,頁面顯示出了英雄列表。 滾動到底部,就會在消息區看到來自 HeroService 的消息。 點擊“清空”按鈕,消息區不見了。

查看最終代碼

你的應用應該變成了這樣 在線例子 / 下載范例。本頁所提及的代碼文件如下。

如果你想直接在 stackblitz 運行本頁中的例子,請單擊鏈接:https://stackblitz.com/github/cwiki-us-angular/cwiki-us-angular-tour-of-hero-services

本頁中所提及的代碼如下:https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-services

對應的文件列表和代碼鏈接如下:

文件名

源代碼

src/app/hero.service.tshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-services/blob/master/src/app/hero.service.ts
src/app/heroes/heroes.component.tshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-services/blob/master/src/app/heroes/heroes.component.ts
src/app/messages/messages.component.tshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-services/blob/master/src/app/messages/messages.component.ts
src/app/messages/messages.component.htmlhttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-services/blob/master/src/app/messages/messages.component.html
src/app/messages/messages.component.csshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-services/blob/master/src/app/messages/messages.component.css
src/app/app.module.tshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-services/blob/master/src/app/app.module.ts
src/app/app.component.htmlhttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-services/blob/master/src/app/app.component.html

小結

  • 你把數據訪問邏輯重構到了 HeroService 類中。

  • 你在根注入器中把 HeroService 注冊為該服務的提供商,以便在別處可以注入它。

  • 你使用 Angular 依賴注入機制把它注入到了組件中。

  • 你給 HeroService 中獲取數據的方法提供了一個異步的函數簽名。

  • 你發現了 Observable 以及 RxJS 庫。

  • 你使用 RxJS 的 of() 方法返回了一個模擬英雄數據的可觀察對象 (Observable<Hero[]>)。

  • 在組件的 ngOnInit 生命周期鉤子中調用 HeroService 方法,而不是構造函數中。

  • 你創建了一個 MessageService,以便在類之間實現松耦合通訊。

  • HeroService 連同注入到它的服務 MessageService 一起,注入到了組件中。

上述內容就是如何理解Angular服務,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武清区| 临海市| 平凉市| 邹平县| 静海县| 葫芦岛市| 万荣县| 平乡县| 沧源| 梅州市| 章丘市| 永丰县| 洪湖市| 郧西县| 灵丘县| 深圳市| 丹东市| 罗定市| 张家口市| 连江县| 城固县| 卫辉市| 志丹县| 巩留县| 莆田市| 五大连池市| 闽清县| 古田县| 辉县市| 朝阳市| 玉田县| 弥勒县| 湖南省| 禄劝| 文山县| 栖霞市| 丹东市| 鲁甸县| 安庆市| 博乐市| 江西省|