【前端】5.Angular实现一个 toDoList 类似京东 App 搜索缓存数据功能【前面知识综合练习】Angular 中的服务以及实现toDoList 数据持久化

参考视频:
https://www.bilibili.com/video/av50917863?p=6
https://www.bilibili.com/video/av50917863?p=7

一、Angular的服务

本文中两个例子都用到了数据持久化的方法,为了避免方法重复定义,引入了服务的概念,这是由于:

  • 组件之间没法相互调用各组件里定义的方法;
  • 多个组件都用的方法(例如数据缓存的方法)放在服务(service)里。
    在这里插入图片描述
    服务的创建和使用:
    在这里插入图片描述
    在这里插入图片描述

二、实例一

本文共实现两个例子,两个例子之间用到的知识点相通,第二个例子是第一个例子的拓展。(可以结合视频和代码好好理解)

实现效果图如下:

在这里插入图片描述

代码部分:

1.创建组件:ng g component components/search
在这里插入图片描述
创建服务: ng g service services/storage
在这里插入图片描述
2.每个文件中的代码
(1)search.component.html中

<h2>京东搜索</h2>
<div class="search">
    <input type="text" [(ngModel)]="keyword"><button (click)="doSearch()" class="button1">搜索</button>
    <hr>
    <ul>
        <li *ngFor="let item of historyList;let key=index;">{{item}}-------<button (click)="deleteHistory(key)">删除</button>
        </li>
    </ul>
</div>

(2)search.component.ts中

import { Component, OnInit } from '@angular/core';
//引入服务,需要注意路径
import { StorageService } from '../../services/storage.service';

//不推荐使用该方法来用服务
    /*实例化类(服务)
    var storage=new StorageService();
    console.log(storage);
    */

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
  //定义属性进行双向数据绑定
  public keyword:string;
  public historyList:any[]=[]; //定义的数组,存储输入的值
  
  //使用服务,实例化,即初始化
  constructor(public storage:StorageService) {
    //let s=this.storage.get();
    //console.log(s);
  
   }

  ngOnInit(): void {
    console.log('页面刷新会触发这个生命周期函数');
    var searchlist:any=this.storage.get('searchlist');
    if(searchlist){
      this.historyList=searchlist;
    }
  }

   //搜索函数
  doSearch(){
   //if语句检查输入的值在列表中是否存在,如果=-1说明不存在,则需要push进去
        if(this.historyList.indexOf(this.keyword)==-1){
          this.historyList.push(this.keyword);//理解push是什么意思
      }

      this.keyword='';
    //获取属性的值
      console.log(this.keyword);

   //缓存数据,实现数据持久化
   this.storage.set('searchlist',this.historyList);
  }

  //删除历史记录函数
  deleteHistory(key){
    //alert(key);
    this.historyList.splice(key,1);//splice可以在数组里删除,增加,修改一个值。在这里表示从key位置往后删除一个值。
    this.storage.set('searchlist',this.historyList);
  }
}

(3)search.component.css中

    .search{
        width: 400px;
        margin: 20px auto;   
    }
    input{
        margin-bottom: 20px;
        width: 300px;
        height: 32px;
    }
    .button1{
        width: 60px;
        height: 35px;
        margin-left: 10px;
    }
    h2{
        /* 标题居中 */
        text-align: center;
}

(4)storage.service.ts中

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

@Injectable({
  providedIn: 'root'
})
export class StorageService {

  constructor() { }
  //set数据
      set(key:string,value:any){
        //H5里的语句,得到数据
        localStorage.setItem(key,JSON.stringify(value));
      }
  //get数据
      get(key:string){
        //理解这句话的意思
        return JSON.parse(localStorage.getItem(key))
      }
  //删除数据
      remove(key:string){
        localStorage.removeItem(key);
      }
 
}

(5)app.component.html中

  <app-search></app-search>

(6)app.module.ts中添加下列代码

//引入这一句,才可以进行双向数据绑定
import { FormsModule } from '@angular/forms';
//引入并且配置服务
import { StorageService } from './services/storage.service';

//服务声明的地方
    providers: [StorageService],

ng serve --o 运行项目即可。

三、实例二

实现效果图如下:

在这里插入图片描述

代码部分:

1.创建组件和服务(服务在实例一中创建了的小伙伴,这里就不用创建服务了)

组件:ng g component components/todolist
在这里插入图片描述
服务:ng g service services/storage
在这里插入图片描述
2. 各个文件中的代码
(1)todolist.component.html中

<h2>todolist</h2>
<div class="todolist">
    <input class="form_input" type="text" [(ngModel)]="keyword" (keyup)="doAdd($event)"/>
    <hr>
    <h3>待办事项</h3>
    <ul>
        <li *ngFor="let item of todolist;let key=index;"[hidden]="item.status==1">
            <!-- (change)表示触发某个事件 -->
            <input type="checkbox" [(ngModel)]="item.status" (change)="checkboxChange()"/>{{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==0">
            <input type="checkbox" [(ngModel)]="item.status" (change)="checkboxChange()"/>{{item.title}}   --------<button (click)="deleteData(key)">X</button>
        </li>
    </ul>
    
</div>

(2)todolist.component.ts中

import { Component, OnInit } from '@angular/core';
//引入服务,需要注意路径
import { StorageService } from '../../services/storage.service';

@Component({
  selector: 'app-todolist',
  templateUrl: './todolist.component.html',
  styleUrls: ['./todolist.component.css']
})
export class TodolistComponent implements OnInit { 
//定义属性进行双向数据绑定
    public keyword:string;
    //定义的数组,存储输入的值,注意todolist数组里的数据格式
    /*public todolist:any[]=[
      {
        title:111,
        status:0
      }
      */
    public todolist:any[]=[];

    //使用服务,实例化,即初始化
      constructor(public storage:StorageService) {
        //let s=this.storage.get();
        //console.log(s);
      
      }
  
      ngOnInit(): void {
        console.log('页面刷新会触发这个生命周期函数');
        var todolist:any=this.storage.get('todolist');
        if(todolist){
          this.todolist=todolist;
        }
      }

//自定义的函数(方法)
    //接听回车事件,一按回车就把输入的内容push到列表中
    //了解对象怎么表示
    doAdd(e){
       if (e.keyCode==13) { //这里判断数据是否存在不可行,因为是一个对象,所以需要封装一个方法
         if(!this.todolistHasKeyword(this.todolist,this.keyword)){
         this.todolist.push(
           {
             title:this.keyword,
             status:0      //0表示待办事项 1代表已完成事项
           }
         )
         this.keyword='';
       
    }else{
      alert('数据已经存在');
      this.keyword='';
    }
  }
  //缓存数据,实现数据持久化
  this.storage.set('todolist',this.todolist);//用到this一定要注意this的指向
  }

    //删除函数
    deleteData(key){
      //alert(key);
      this.todolist.splice(key,1);//splice可以在数组里删除,增加,修改一个值。在这里表示从key位置往后删除一个值。
      this.storage.set('todolist',this.todolist);
}

//封装方法
//如果数组里面有keyword返回true,否则返回false
todolistHasKeyword(todolist:any,keyword:any){

  //异步 会存在问题
        /*todolist.forEach(value => {
          if (value.title==keyword) {
            return true;
          }
        });
        */

  //另一种方法,用到for循环
    if (!keyword) return false;
    for (var i=0;i<todolist.length;i++) {
      if (todolist[i].title==keyword) {
        return true;
      }  
    }
  return false;

}
checkboxChange(){
  console.log('事件触发了');
  this.storage.set('todolist',this.todolist);//用到this一定要注意this的指向

}
}

(3)todolist.component.css中

h2{
    /* 标题居中 */
    text-align: center; 

}

.todolist{
    width: 400px;
    margin: 20px auto;   
}
.form_input{
    margin-bottom: 20px;
    width: 300px;
    height: 32px;
}
li{
    /* 行高 */
    line-height: 40px;
}

(4)storage.service.ts中

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

@Injectable({
  providedIn: 'root'
})
export class StorageService {

  constructor() { }
  //set数据
      set(key:string,value:any){
        //H5里的语句,得到数据
        localStorage.setItem(key,JSON.stringify(value));
      }
  //get数据
      get(key:string){
        //理解这句话的意思
        return JSON.parse(localStorage.getItem(key))
      }
  //删除数据
      remove(key:string){
        localStorage.removeItem(key);
      }
 
}

(5)app.component.html中

  <app-todolist></app-todolist>

(6)app.module.ts中添加下列代码

//引入这一句,才可以进行双向数据绑定
import { FormsModule } from '@angular/forms';
//引入并且配置服务
import { StorageService } from './services/storage.service';

//服务声明的地方
    providers: [StorageService],

ng serve --o 运行项目即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值