Angular中创建和使用服务

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>

运行效果

在这里插入图片描述

增加按钮

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电脑显示丢失mfc140u.dll怎么修复,总共有7个方法

mfc140u.dll 是一个动态链接库&#xff08;Dynamic Link Library&#xff09;文件&#xff0c;它是Microsoft Foundation Class (MFC)库的一部分&#xff0c;专为使用C编程语言开发Windows应用程序而设计。MFC库由微软提供&#xff0c;作为一个高级的应用程序框架&#xff0c;旨…

通过 Java 操作 redis -- 连接 redis

如果我们想在本地主机上访问 Linux 服务器上的 redis &#xff0c;我们就需要通过 ssh 进行端口转发&#xff0c;推荐看 本地主机访问服务器的Redis -- 配置 ssh 端口转发 通过 Java 操作 redis 已经有大佬创建了很多第三方库&#xff0c;这里我们使用 jedis &#xff0c;因为它…

N7552A是德科技N7552A电子校准件

181/2461/8938产品概述&#xff1a; 更小巧轻便的 2 端口模块&#xff0c;支持 3.5 mm 或 N 型 50 Ω 连接器&#xff0c;能够将校准时间缩短一半 特点 频率范围&#xff1a;直流至 9 GHz 使用 N 型或 3.5 mm 连接器 更小巧轻便的 2 端口电子校准件&#xff08;ECal&#xff…

Linux:进程等待 进程替换

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

《Fundamentals of Power Electronics》——示例:Buck-Boost转换器模型变为正则形式

为了说明正则电路模型推导的步骤&#xff0c;让我们将buck-boost转换器的等效电路操作成规范形式。buck-boost转换器的一个小信号交流等效电路如下图所示。 为了将上图所示网络转换成正则形式&#xff0c;需要将所有独立源d(t)转换到左侧&#xff0c;而将所有电感转换到右侧与变…

PHP 匿名函数和闭包在数据结构中的应用

匿名函数和闭包在数据结构处理中的应用php 中的匿名函数和闭包可用于处理数组、链表和队列等数据结构。针对数组&#xff0c;匿名函数可用于过滤元素&#xff1b;针对链表&#xff0c;闭包可用于创建节点&#xff1b;针对队列&#xff0c;匿名函数和闭包可实现 fifo 队列操作。…

css 文字描边

又是抄样式的一天。这次是百度地图。实现了问题和图形描边的效果。 代码&#xff1a; .BMap_scaleTxt.dark {color: #fff;text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; } 效果&#xff1a;

uniapp打包的程序在Xcode中运行到模拟器报错的解决方法

uniapp打包的程序在Xcode中运行到模拟器报错的解决方法 问题描述&#xff1a; Building for iOS-simulator, but linking in object file (/Users/hori/Documents/SDK/SDK/Libs/DCUniRecord.framework/DCUniRecord[arm64][3](PGRecord.o)) built for iOS Linker command fail…

翻译《The Old New Thing》- Does Windows have a limit of 2000 threads per process?

Does Windows have a limit of 2000 threads per process? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20050729-14/?p34773 Raymond Chen 2005年07月29日 Windows 是否有一个每个进程2000线程的限制&#xff1f; 简要 文章解释了在 W…

快速搭建linux虚拟机环境

1、虚拟机资源 VMwareWorkstation&#xff1a;Download VMware Workstation Pro virtualbox&#xff1a;Oracle VM VirtualBox 2、虚拟机系统资源 链接&#xff1a;系统资源链接 提取码&#xff1a;0gat 说明&#xff1a;此处的系统资源是采用VMwareWorkstation 虚拟机进…

vue脚手架和vite创建的项目的环境配置

开发环境文件 .env.development NODE_ENV"development" # // 开发接口域名 本地测试就用这个 # vue脚手架创建的 VUE_APP_MODE"开发环境" VUE_APP_API_URL http://19527 # vite创建的 # VITE_MODE"开发环境" # VITE_BASE_URL http://1920:9527…

【自动驾驶|毫米波雷达】逻辑化讲清快时间与慢时间傅里叶变换

碎碎念&#xff1a;实习过程中发现在进行雷达知识交流时&#xff0c;大部分同事都会用英文简称代替中文的一些称呼&#xff0c;比如Chirp、FFT等等。起初我觉得是因为很多英伟达、TI芯片的开发教程都是英文的&#xff0c;所以看得多了大家都习惯这样称呼&#xff0c;后来在和指…

Linux高级学习(前置 在vmware安装centos7.4)

【小白入门 通俗易懂】2021韩顺平 一周学会Linux 此文章包含第006p-第p007的内容 操作 在安装好的vmware下进行安装 这里使用的是vmware15&#xff08;win10下&#xff09;&#xff0c;win11可能无法使用15&#xff08;有几率蓝屏&#xff09;&#xff0c;换成16就行了 用迅雷…

将PT脚本转化为innovus脚本

前一节写的关于PT修时序后吐出相关脚本&#xff0c;但是无法直接使用APR工具innovus进行时序修复&#xff0c;此节介绍一种利用perl脚本将吐出脚本转化为innovus可读的脚本 1.转化前文本形式 2&#xff0c;转化后脚本 3.perl 脚本正文 #&#xff01;/usr/bin/perl #transla…

【完美解决】使用git时候出现error setting certificate verify locations: CAfile:问题

1、出现场景&#xff1a; 在使用idea的时候&#xff0c;进行git下的push&#xff0c;出现下面的错误&#xff1a; 2、原因分析&#xff1a; 可能因为重装过系统&#xff0c;或者是安装git的位置发生了变化等情况出现。 3、解决方案&#xff1a; 找到git的安装路径&#xf…

Layer创建流程

在SurfaceFlinger中&#xff0c;Layer表示一个显示图层&#xff0c;是surfaceflinger合成过程中最重要的基本单元&#xff0c;它提供了一系列属性定义了如何参与合成并与其他Layer交互&#xff0c;包括&#xff1a; 位置&#xff1a;定义Layer出现在屏幕上的位置&#xff0c;包…

回归分析的理解

1.是什么&#xff1a; 2.回归问题的求解&#xff1a; 首先是根据之前的数据确定变量和因变量的关系根据关系去预测目标数据根据结果做出判断 2.1如何找到关系&#xff1f; y’是根据模型生成的预测结果&#xff1a; y’axb&#xff0c;而我们的目的是y’和y(正确的结果)之间…

Innodb实现的索引

概念 一种用于提高数据库查询性能的有序的数据结构。通过使用索引&#xff0c;数据库引擎可以快速定位到存储表中的特定数据&#xff0c;而不必逐行遍历整个表。在处理大量数据的时候可以显著加快数据检索的速度。 通过索引列队数据进行排序&#xff0c;降低数据排序的成本&a…

V23 中的新功能:LEADTOOLS 展示了它的 EXCEL-lence

LEADTOOLS (Lead Technology)由Moe Daher and Rich Little创建于1990年&#xff0c;其总部设在北卡罗来纳州夏洛特。LEAD的建立是为了使Daher先生在数码图象与压缩技术领域的发明面向市场。在过去超过30年的发展历程中&#xff0c;LEAD以其在全世界主要国家中占有的市场领导地位…

Verilog中4位数值比较器电路

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