注:以下内容来源教程 https://www.bilibili.com/video/BV1bt411e71b/?spm_id_from=333.337.search-card.all.click&vd_source=d24d4d209aa65e8fc37220ced9cbcf2f
一、Angular 的服务
Angular 中各个组件之间是不能调用彼此的方法的,但是如果有一些方法是公共的,多个组件都要用到,这个时候就可以使用服务啦。
1.定义服务
Angular中可以使用命令 ng g service 服务名 定义一个服务。
ng g service services/storage
输入命令回车之后,会在相应的路径下生成对应服务。
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class StorageService {
constructor() { }
// 组件都可以调用的方法
get() {
return 'This is a service.';
}
}
2.引入并声明服务
在 app.module.ts 中引入创建的服务,并且声明。
// NgModule:Angular 核心模块
import { NgModule } from '@angular/core';
// BrowserModule:浏览器解析的模块
import { BrowserModule } from '@angular/platform-browser';
// 引入表单模块
import { FormsModule } from '@angular/forms';
// AppComponent:根组件
import { AppComponent } from './app.component';
// 引入并配制服务
import { StorageService } from './services/storage.service';
// @NgModule装饰器:接受一个元数据对象,告诉 Angular 如何编译和启动应用
@NgModule({
declarations: [ // 配置当前项目运行的组件
AppComponent,
],
imports: [ // 配置当前模块运行依赖的其他模块
BrowserModule,
FormsModule
],
providers: [StorageService], // 配置项目所需要的服务
bootstrap: [AppComponent] // 指定应用的主视图(称为根组件),通过引导根 AppModule 来启动应用,这里一般写的是根组件
})
// 根模块不需要导出任何东西,因为其他组件不需要导入根模块
export class AppModule { }
3.使用服务
组件不能使用组件,但是组件都可以使用服务,并且服务也可以使用服务。
组件使用服务之前还需要引入服务,然后在构造函数中初始化服务,接下来就可以使用啦。
import { Component } from '@angular/core';
// 引入服务
import { StorageService } from 'src/app/services/storage.service';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent {
constructor(public storage:StorageService) {
let s = this.storage.get();
console.log(s);
}
}
二、案例:toDoList的实现以及数据持久化
1.页面效果
2.页面结构
代码如下:
<h2>toDoList</h2>
<div class="todolist">
<input type="text" [(ngModel)]="keyWord" (keyup)="doAdd($event)" class="keyWord">
<hr>
<h3>待办事项</h3>
<ul>
<!-- 不能在一个元素上使用多个指令 -->
<li *ngFor="let item of todoList;let key = index;" [hidden]="item.status">
<input type="checkbox" [(ngModel)]="item.status" (change)="checkBox()">
{{ item.title }} ------ <button (click)="deleteData(key)">x</button>
</li>
</ul>
<h3>已完成事项</h3>
<ul>
<li *ngFor="let item of todoList;let key = index;" [hidden]="!item.status">
<input type="checkbox" [(ngModel)]="item.status" (change)="checkBox()">
{{ item.title }} ------ <button (click)="deleteData(key)">x</button>
</li>
</ul>
</div>
3.页面样式
代码如下:
h2 {
text-align: center;
}
.todolist {
width: 400px;
margin: 20px auto;
}
.todolist .keyWord {
margin-bottom: 20px;
width: 300px;
height: 32px;
margin-right: 5px;
}
ul, li {
list-style: none;
line-height: 50px;
}
4.数据持久化服务
代码如下:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class StorageService {
constructor() { }
set(key:string, value:any) {
localStorage.setItem(key, JSON.stringify(value));
}
// 组件都可以调用的方法
get(key:string) {
return JSON.parse(localStorage.getItem(key)||'[]');
}
remove(key:string) {
localStorage.removeItem(key);
}
}
5.页面逻辑
代码如下:
import { Component } from '@angular/core';
// 引入服务
import { StorageService } from 'src/app/services/storage.service';
@Component({
selector: 'app-todolist',
templateUrl: './todolist.component.html',
styleUrls: ['./todolist.component.css']
})
export class TodolistComponent {
// 搜索关键词
public keyWord:string = '';
// 搜索历史列表
public todoList:any[] = [];
constructor(public storage:StorageService) {}
ngOnInit() {
let todoList:any = this.storage.get('todolist');
if(todoList) {
this.todoList = todoList;
}
}
doAdd(e:any) {
if(e.keyCode === 13) {
if(!this.toDoListHasKeyword(this.todoList, this.keyWord)) {
this.todoList.push({
title: this.keyWord,
status: false
});
this.storage.set('todolist', this.todoList);
} else {
alert('数据已经存在!');
}
this.keyWord = '';
}
}
deleteData(key:any) {
// 从数组下标key开始删除一个值
this.todoList.splice(key, 1);
this.storage.set('todolist', this.todoList);
}
toDoListHasKeyword(todoList: any[], keyWord: any) {
// 异步,会存在问题
// todoList.forEach(value => {
// if(value.title === keyWord) {
// return true;
// }
// });
for(let i = 0; i < todoList.length; i++) {
if(todoList[i].title === keyWord) {
return true;
}
}
return false;
}
checkBox() {
this.storage.set('todolist', this.todoList);
}
}