Angular中创建和使用服务

news2024/11/26 10:46:13

Angular中的服务


文章目录

  • Angular中的服务
    • 前言
    • 一、创建服务
    • 二、使用服务


前言

Angular 服务是 Angular 应用程序中用于封装可重用逻辑的类。服务在应用程序的多个组件之间共享数据和功能,而不依赖于应用程序的UI。服务可以用于诸如数据处理、与后端通信、用户身份验证等任务。

Angular 把数据与业务进行了抽离,希望我们能够单一的专注于数据的处理和数据的展示。所以就建立了服务的概念。这里的服务不是后台中的服务,本质是函数的封装。封装很多方法,对数据进行处理和返回。

以下是 Angular 服务的一些关键点:

  • 依赖注入: Angular服务通过依赖注入(DI)系统在应用程序中使用。这意味着组件或其他服务可以请求服务的实例,而不需要知道如何创建这些实例。
  • 单例模式: 默认情况下,Angular 服务是单例的,这意味着每个服务类在应用程序中只有一个实例。
  • 惰性初始化: 服务只在第一次请求时创建,之后每次请求都会返回同一个实例。
  • 服务定义: 使用 @Injectable 装饰器定义服务,并通过 providedIn 属性或在模块中手动添加来指定服务的作用域。
  • 服务使用: 组件或其他服务可以通过构造函数注入来使用服务。

一、创建服务

使用命令创建

ng g service 服务名

在这里我在services目录下创建一个data服务

ng g service services/data

在这里插入图片描述

这个组件就创建好了。

二、使用服务

使用命令创建data组件

ng g component components/data

在这里插入图片描述
在服务中写一些功能

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'// 这里的'root'意味着服务将在整个应用中可用
})
export class DataService {

  constructor() { }
  // 示例数据 
  private data: any[] = [
    { id: 1, name: 'Item 1' },
    { id: 2, name: 'Item 2' },
    { id: 3, name: 'Item 3' },
    { id: 4, name: 'Item 4' },
    { id: 5, name: 'Item 5' },
    { id: 6, name: 'Item 6' },
    { id: 7, name: 'Item 7' },
    { id: 8, name: 'Item 8' },
    { id: 9, name: 'Item 9' },
    { id: 10, name: 'Item 10' }
  ];
  
  // 获取数据的方法  
  getData(): any[] { 
    console.log('DataService: getData() called'  + '   ' +this.data.length);
    return this.data;  
  }  
  
  // 添加数据的方法  
  addData(item: any) {  
    this.data.push(item);  
  } 

  // 移除数据的方法  
  removeData(item: any) {  
    this.data = this.data.filter(x => x !== item);
  } 
}

在 Angular 中,@Injectable 装饰器的 providedIn 属性用于指定服务的作用域,即在哪里提供这个服务的实例。providedIn: ‘root’ 表示该服务是单例的,并且由 Angular 的根模块(通常是 AppModule)提供。

除了root,providedIn 还可以有以下几种使用方式:

  • root:服务作为单例在整个应用程序中只有一个实例。这是默认的提供方式,适用于大多数服务。
  • any:服务可以在任何模块中提供,并且可以在多个模块中多次提供,每次提供都将创建一个新的实例。
  • platform:服务只在平台(例如服务器端或 Web Worker)上提供,而不是在浏览器的主渲染线程上。
  • NgModule:服务在特定的 NgModule 中提供。这意味着服务的实例只在该模块及其导入的模块中可用。
  • module:后面跟上具体的模块类,例如 providedIn: MyModule,服务只在该模块及其导入的模块中提供。

还可以使用null,实际上是在告诉 Angular 的依赖注入系统不要自动提供这个服务,这样做之后,你需要手动在模块的 providers 数组中注册服务。

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: null // 显式地告诉 Angular 不要自动提供这个服务
})
export class MyService {
  // 服务逻辑
}

在模块中手动添加这个服务到 providers 数组中:

import { NgModule } from '@angular/core';
import { MyService } from './my.service';

@NgModule({
  // ... 其他模块元数据
  providers: [MyService] // 手动提供服务
})
export class MyModule {
  // 模块逻辑
}

使用 providedIn: null 主要有几个用途:

  • 控制服务的作用域:你想要控制服务实例的作用域,比如仅在一个特定的模块及其子模块中可用。
  • 避免单例模式:虽然 Angular 默认创建服务的单例,但通过手动提供服务,你可以在不同模块中创建服务的多个实例。
  • 延迟提供服务:在某些情况下,你可能希望延迟服务的创建,直到它实际上被需要,这可以通过手动提供服务来实现。
  • 兼容性:如果你正在维护一个旧的 Angular 应用程序,并且想要保持对旧行为的兼容性,使用 null 可以给你更多的控制。

总的来说,使用 null 提供服务是一种更明确和手动的方法,它允许开发者更精确地控制服务的生命周期和作用域。然而,这也意味着你需要更仔细地管理服务的注册和使用,以避免错误或不一致的行为。

要使用服务,首先需要将其注入到组件中。你可以通过组件的构造函数注入服务:

  constructor(private dataService: DataService) { }

data.component.ts

import { Component } from '@angular/core';
import { DataService } from '../../services/data.service';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-data',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './data.component.html',
  styleUrl: './data.component.css'
})
export class DataComponent {

  items: any[]=[];

  constructor(private dataService: DataService) { }

  ngOnInit() :void{
    this.items = this.dataService.getData(); // 调用服务方法获取数据  
  }

  addItem(): void {
    let iCount = this.items.length+1;
    console.log(iCount);
    this.dataService.addData( { id: iCount, name: 'Item ' + iCount})
    alert('Item ' + iCount+' 添加成功');
  }

  removeItem(): void {
    if(this.items.length===0)
    {
      alert('没有数据可删');
      return;
    }
    console.log('删除前'+ this.items.length);
    let lastItem = this.items[this.items.length-1];
    this.dataService.removeData(lastItem);
    this.items = this.dataService.getData();
    console.log('删除后'+ this.items.length);
    alert(lastItem.name+' 删除成功');
  }
}

在imports里面加上CommonModule,不然html里面的*ngFor会有提醒。

data.component.html

<p>data works!</p>

<div>
    <button (click)="addItem()">增加数据</button>
    <button (click)="removeItem()">删除数据</button>
</div>

<div *ngFor="let item of items" >  
    <p>{{ item.name }}</p>  
</div>
<!-- @for (item of items; track $index) {

    <p>{{ item.name }}</p>  
} -->
<p>data works end!</p>

app.component.ts

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { DataComponent } from './components/data/data.component';

@Component({
    selector: 'app-root',
    standalone: true,
    templateUrl: './app.component.html',
    styleUrl: './app.component.css',
    imports: [RouterOutlet, DataComponent]
})
export class AppComponent {
  title = 'first-component';
}

app.component.html

<p>这个是app</p>

<app-data></app-data>

运行效果

在这里插入图片描述

增加按钮

在这里插入图片描述
在这里插入图片描述
删除数据
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1650984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Verilog中4位数值比较器电路

某4位数值比较器的功能表如下。 请用Verilog语言采用门级描述方式&#xff0c;实现此4位数值比较器 参考代码如下&#xff1a; &#xff08;CSDN代码块不支持Verilog&#xff0c;代码复制到notepad编辑器中&#xff0c;语言选择Verilog&#xff0c;看得更清楚&#xff09; t…

芸众商城电商专业版400+插件源码+搭建教程

介绍&#xff1a; 芸众商城社交电商系统SAAS平台前端基于vue开发&#xff0c;后端基于研发积分商城系统源码 php&#xff0c;本文安装芸众商城全插件&#xff08;400多个&#xff09;商业版平台源码&#xff0c;可同时支持多端口部署运行&#xff1b;使用宝塔面板一键部署的形…

Linux:进程等待 进程替换

Linux&#xff1a;进程等待 & 进程替换 进程等待wait接口statuswaitpid接口 进程替换exec系列接口 当一个进程死亡后&#xff0c;会变成僵尸进程&#xff0c;此时进程的PCB被保留&#xff0c;等待父进程将该PCB回收。那么父进程要如何回收这个僵尸进程的PCB呢&#xff1f;父…

bfs之八数码

文章目录 八数码解题思路图解举例算法思路 代码CPP代码Java代码 八数码 在一个 33的网格中&#xff0c;1∼8这 8个数字和一个 x 恰好不重不漏地分布在这 33 的网格中。 例如&#xff1a; 1 2 3 x 4 6 7 5 8在游戏过程中&#xff0c;可以把 x 与其上、下、左、右四个方向之一…

学成在线 - 第3章任务补偿机制实现 + 分块文件清理

7.9 额外实现 7.9.1 任务补偿机制 问题&#xff1a;如果有线程抢占了某个视频的处理任务&#xff0c;如果线程处理过程中挂掉了&#xff0c;该视频的状态将会一直是处理中&#xff0c;其它线程将无法处理&#xff0c;这个问题需要用补偿机制。 单独启动一个任务找到待处理任…

scikit-learn实现单因子线性回归模型

1.是什么&#xff1a; 针对机器学习提供了数据预处理&#xff0c;分类&#xff0c;回归等常见算法的框架 2.基于scikit-learn求解线性回归的问题&#xff1a; 2.1.求解a&#xff0c;b对新数据进行预测&#xff1a; 2.2评估模型表现&#xff08;y和y’的方差MSE&#xff09;…

论文查重率高,有什么办法降重吗?

现在大部分学校已经进入到论文查重降重的阶段了。如果查重率居高不下&#xff0c;延毕的威胁可能就在眼前。对于即将告别校园的学子们&#xff0c;这无疑是个噩梦。四年磨一剑&#xff0c;谁也不想在最后关头功亏一篑。 查重率过高&#xff0c;无非以下两种原因。要么是作为“…

小程序搜索排名优化 三步操作提升

搜索排名优化最直接的一个目的就是为了提升小程序的排名和流量&#xff0c;获取用户的信任度。当用户在搜索关键词的时候&#xff0c;能让用户看到小程序&#xff0c;增加被发现和点击的机会。 一、关键词优化&#xff1a; 1.选择合适的关键词&#xff1a;选择与小程序内容高…

解决Gitlab集成Jira时报SSL证书问题

1. 问题描述 在gitlab中集成jira的时候&#xff0c;由于jira是企业内部网址&#xff0c;并使用自己签名的SSL证书&#xff0c;一直会报证书验证不过的问题&#xff0c;报错信息如下&#xff1a; Connection failed. Check your integration settings. SSL_connect returned1 …

odoo实施之各种导航设计

odoo各种基础能力&#xff1a;活动、讨论 玩转odoo&#xff0c;真有玩的体验 odoo消息提醒能力 odoo 讨论模块 odoo 通过new message触发任务 安装odoo studio进行拖拉拽设计 查阅官方文档&#xff0c;向官方提issue 欧洲和美国&#xff0c;虽然都是英语&#xff0c;但日期格式…

win10下,svn上传.so文件失败

问题&#xff1a;win10下使用TortoiseSVN&#xff0c;svn上传.so文件失败 解决&#xff1a;右键&#xff0c;选择Settings&#xff0c;Global ignore pattern中删除*.so&#xff0c;保存即可。

Verilog中4bit超前进位加法器

4bit超前进位加法器的逻辑表达式如下&#xff1a; 中间变量GiAiBi&#xff0c;PiAi⊕BiGi​Ai​Bi​&#xff0c;Pi​Ai​⊕Bi​ 和&#xff1a;SiPi⊕Ci−1Si​Pi​⊕Ci−1​&#xff0c;进位&#xff1a;CiGiPiCi−1Ci​Gi​Pi​Ci−1​ 用Verilog语言采用门级描述方式&am…

页面嵌套,界面套娃,除了用iframe,还有其他方式吗?

UIOTOS可以了解下&#xff0c;uiotos.net&#xff0c;通过连线来代替脚本逻辑开发&#xff0c;复杂的交互界面&#xff0c;通过页面嵌套轻松解决&#xff0c;是个很新颖的思路&#xff0c;前端零代码&#xff01; 蓝图连线尤其是独创的页面嵌套和属性继承技术&#xff0c;好家…

如何使用dockerfile文件将项目打包成镜像

要根据Dockerfile文件来打包一个Docker镜像&#xff0c;你需要遵循以下步骤。这里假设你已经安装了Docker环境。 1. 准备Dockerfile 确保你的Dockerfile文件已经准备就绪&#xff0c;并且位于你希望构建上下文的目录中。Dockerfile是一个文本文件&#xff0c;包含了用户可以调…

vue3专栏项目 -- 项目介绍以及准备工作

这是vue3TS的项目&#xff0c;是一个类似知乎的网站&#xff0c;可以展示专栏和文章的详情&#xff0c;可以登录、注册用户&#xff0c;可以创建、删除、修改文章&#xff0c;可以上传图片等等。 这个项目全部采用Composition API 编写&#xff0c;并且使用了TypeScript&#…

【k8s多集群管理平台开发实践】八、client-go实现service读取列表、创建service、读取yaml配置并更新

文章目录 简介 一.k8s的service列表1.1.controllers控制器代码1.2.models模型代码 二.创建service2.1.controllers控制器代码2.2.models模分代码 三.读取和更新service的yaml配置3.1.controllers控制器代码3.2.models模型代码 四.路由设置4.1.路由设置 五.前端代码5.1.列表部分…

湖仓一体 - Apache Arrow的那些事

湖仓一体 - Apache Arrow的那些事 Arrow是高性能列式内存格式标准。它的优势&#xff1a;高效计算&#xff1a;所有列存的通用优势&#xff0c;CPU缓存友好、SIMD向量化计算友好等&#xff1b;零序列化/反序列化&#xff1a;arrow的任何数据结构都是一段连续的内存&#xff0c;…

基于单片机的无线数据传输系统设计

摘要:基于单片机的无线数据传输系统的设计,实现了温度和湿度的自动采集、无线通讯和报警功能。该系统包括了LCD1602显示电路、DHT11温湿度采集电路等,完成了基于无线数据传输的方法来实现温湿度的采集。 关键词:温湿度检测;N RF 24 L 01;单片机 0 引言 随着科技水平的提高,…

将矩阵按对角线排序(Lc1329)——排序

矩阵对角线 是一条从矩阵最上面行或者最左侧列中的某个元素开始的对角线&#xff0c;沿右下方向一直到矩阵末尾的元素。例如&#xff0c;矩阵 mat 有 6 行 3 列&#xff0c;从 mat[2][0] 开始的 矩阵对角线 将会经过 mat[2][0]、mat[3][1] 和 mat[4][2] 。 给你一个 m * n 的整…

Mac 链接 HP 136w 打印机步骤

打开 WI-FI 【1】打开打印机左下角Wi-Fi网络设计【或者点击…按钮进入WI-FI菜单】&#xff0c;找到NetWork选项OK进入&#xff1b; 【2】设置WI-FI选项&#xff1a;在菜单内找到Wi-Fi选项OK进入&#xff1b; 【3】在菜单内找到Wi-Fi Direct选项OK进入&#xff1b; 【4】在菜单…