Angular 学习笔记 (五) - 服务Service和依赖注入

参考官方文档:https://angular.cn/tutorial/toh-pt4

 

一.服务

组件不应该直接获取或保存数据,它们不应该了解是否在展示假数据。 它们应该聚焦于展示数据,而把数据访问的职责委托给某个服务。

Service的作用便可以减少数据在不同模块之间的耦合,简化代码。

创建Service指令:

ng generate service hero

Service的结构:

复制代码
 1 import { Injectable } from '@angular/core';
 2 
 3 @Injectable({
 4   providedIn: 'root',
 5 })
 6 export class HeroService {
 7 
 8   constructor() { }
 9 
10 }
复制代码

 这里 providedIn: 'root' 的可以将Service声名为App的根目录,适用于作为一个单例服务

 

二.依赖注入

服务导入了 Angular 的 Injectable 符号,并且给这个服务类添加了 @Injectable() 装饰器。 它把这个类标记为依赖注入系统的参与者之一。

@Injectable() 装饰器会接受该服务的元数据对象,就像 @Component() 对组件类的作用一样。

你必须先注册一个服务提供者,来让 Service 在依赖注入系统中可用,Angular 才能把它注入到 Component 中。所谓服务提供者就是某种可用来创建或交付一个服务的东西;在这里,它通过实例化 HeroService 类,来提供该服务。

为了确保 HeroService 可以提供该服务,就要使用注入器来注册它。注入器是一个对象,负责当应用要求获取它的实例时选择和注入该提供者。

一个依赖注入的示例:

Recipe数据模型:

复制代码
 1 import { Ingredient } from '../shared/ingredient.model';
 2 
 3 export class Recipe {
 4   public name: string;
 5   public description: string;
 6   public imagePath: string;
 7   public ingredients: Ingredient[];
 8 
 9   constructor(name: string, desc: string, imagePath: string, ingredients: Ingredient[]) {
10     this.name = name;
11     this.description = desc;
12     this.imagePath = imagePath;
13     this.ingredients = ingredients;
14   }
15 }
复制代码

服务:

复制代码
 1 import { EventEmitter, Injectable } from '@angular/core';
 2 
 3 import { Recipe } from './recipe.model';
 4 import { Ingredient } from '../shared/ingredient.model';
 5 import { ShoppingListService } from '../shopping-list/shopping-list.service';
 6 
 7 @Injectable()
 8 export class RecipeService {
 9   recipeSelected = new EventEmitter<Recipe>();
10 
11   private recipes: Recipe[] = [
12     new Recipe(
13       'Tasty Schnitzel',
14       'A super-tasty Schnitzel - just awesome!',
15       'https://upload.wikimedia.org/wikipedia/commons/7/72/Schnitzel.JPG',
16       [
17         new Ingredient('Meat', 1),
18         new Ingredient('French Fries', 20)
19       ]),
20     new Recipe('Big Fat Burger',
21       'What else you need to say?',
22       'https://upload.wikimedia.org/wikipedia/commons/b/be/Burger_King_Angus_Bacon_%26_Cheese_Steak_Burger.jpg',
23       [
24         new Ingredient('Buns', 2),
25         new Ingredient('Meat', 1)
26       ])
27   ];
28 
29   constructor(private slService: ShoppingListService) {}
30 
31   getRecipes() {
32     return this.recipes.slice();
33   }
34 
35   addIngredientsToShoppingList(ingredients: Ingredient[]) {
36     this.slService.addIngredients(ingredients);
37   }
38 }
复制代码

这里 ShoppingListService 是另一个服务,服务中可以注入另一个服务 

 服务注入Component:

recipes.component.ts:

复制代码
 1 import { Component, OnInit } from '@angular/core';
 2 
 3 import { Recipe } from './recipe.model';
 4 import { RecipeService } from './recipe.service';
 5 
 6 @Component({
 7   selector: 'app-recipes',
 8   templateUrl: './recipes.component.html',
 9   styleUrls: ['./recipes.component.css'],
10   providers: [RecipeService]
11 })
12 export class RecipesComponent implements OnInit {
13   selectedRecipe: Recipe;
14 
15   constructor(private recipeService: RecipeService) { }
16 
17   ngOnInit() {
18     this.recipeService.recipeSelected
19       .subscribe(
20         (recipe: Recipe) => {
21           this.selectedRecipe = recipe;
22         }
23       );
24   }
25 }
复制代码

 

三. 依赖注入的层级

Root注入器并不是Angular应用中唯一的注入器。Modules 和 Components也有自己的注入器。Angular应用的注入器遵循一个层级制度

每当Angular组件在其构造函数中定义了Token时,注入器就会在已注册提供者池中搜索与该Token匹配的类型。如果没有匹配,它将在父组件的提供者上委托搜索,并不断向注册器树上级找寻,直到root注入器如果提供者查找结束时没有匹配,它将返回

如果没有找到匹配项,Angular就会抛出异常。

注入器树:

 

 当组件寻求依赖时:

1st pass: 组件会依次来搜寻父组件,如果找到依赖,则停止寻找并请求改实例,若没有找到,进入2nd pass

2nd pass: 组件依次搜寻其父Module直到root,如果找到依赖,则停止寻找并请求改实例,如果没有找到,则抛出error

 

posted @   Asp1rant  阅读(425)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2020-04-08 用npm server和webpack进行web部署
2019-04-08 Springboot中的事件Event
点击右上角即可分享
微信分享提示