一、实现搜索框的部分代码
【注:涉及api接口和中后台数据交互】
1. 最终呈现形式:
2. 代码实现:
HTML文件中:
<!-- 搜索框部分 --><div class="search-bar" fxFlexAlign="center" style=" margin: 0 auto;max-width: 700px;"><div ngbDropdown fxLayout="row"style="border: none;padding: 0;margin: 0;width: 100%;"><button class="out-btn" id="dropdownBasic1" ngbDropdownToggle fxFlex=18style="border: none;margin-bottom: 7px;background-color: #fff;height: 36px;">易出</button><div ngbDropdownMenu aria-labelledby="dropdownBasic1" style="width: 100%;" ><ul class="history" fxLayout="column"><li class="history-title">最近搜索<button (click)="deleteHistory()" class="delete-all-btn" >清除</button></li><li *ngFor="let item of historyList;let key=index;"><a (click)="doSearch1(item)">{{item}}<button (click)="deleteOneHistory(key)" class="delete-btn"><i class="material-icons">remove_circle_outline</i></button></a></li></ul></div><input class="searcch-inp" type="text" [(ngModel)]="model" [ngbTypeahead]="search" [resultFormatter]="formatter" fxFlex(keyup)="doAdd($event)" placeholder="{{ 'product-list.title3' | translate }}"><button class="search-btn" fxFlex="30 1 1" (click)="doSearch()" (click)="doStorage()"><i class="material-icons">search</i>搜索</button></div></div>
TS文件中:
export class ProductListComponent implements OnInit {//图片懒加载defaultImage = '../../../assets/img/ebarter.jpg';protected:any;rprice:any=[];price:any=[];title:any=[];rtitle:any=[];local:any=[];rlocal:any=[];bgPictrue:any=[];bgPictrue_raw:any=[];bgPictrue_rep:any=[];bgPictrue_str:any=[];bgPictrue_r:any=[];bgPictrue_raw_r:any=[];bgPictrue_rep_r:any=[];bgPictrue_str_r:any=[];awsImgUrl:string = 'https://s3.cn-north-1.amazonaws.com.cn/linda-trades-archive-1/';public list:any;//声明新的对象数组public productList:any=[];public currentPage:any;public rlist:any;public pObj:any=[];public temp:any=[];//搜索商品price_s:any=[];title_s:any=[];local_s:any=[];rlocal_s:any=[];bgPictrue_s:any=[];bgPictrue_raw_s:any=[];bgPictrue_rep_s:any=[];bgPictrue_str_s:any=[];public pObj_s:any=[];//搜索商品的定义public slist:any;//声明新的对象数组public searchList1:any=[];//2.搜索提示数组states:any= [];//3.定义属性进行双向数据绑public model: any;public historyList:any=[]; //定义的数组,存储输入的值//3.使用服务,实例化,即初始化// 初始化路由constructor(private product:ProductService,private storageServe: StorageService,private sanitizer:DomSanitizer,public storage:StorageService,private route: ActivatedRoute,private router: Router,private homeService: HomeService,//搜索框private http: HttpClient,@Inject(API_CONFIG) private uri: string,) { }ngOnInit(): void {//数据持久化console.log('页面刷新会触发这个生命周期函数');var searchlist:any=this.storage.get('searchlist');if(searchlist){this.historyList=searchlist;}//获得产品列表this.product.productlist().subscribe(product => {console.log('productlist',product);var re = /:/gi;this.list = product;this.list= this.list.filter(function(item){return JSON.parse(item.content.toString()).isOnSale == 'yes';})var listLength = this.list.length;var userID = this.storageServe.getStorage('UserID');for(var i = 0;i<listLength;i++){this.pObj[i] = JSON.parse(this.list[i].content.toString());this.title.push(this.pObj[i].supplierAds[0].m_title);this.price.push(this.pObj[i].supplierAds[0].m_price);this.local.push(this.pObj[i].supplierAds[0].m_supplierInfo.region);this.bgPictrue_raw.push(this.pObj[i].supplierAds[0].m_supplierOrderId);this.bgPictrue_rep[i] = this.bgPictrue_raw[i].replace(re,"-");this.bgPictrue_str[i] = this.awsImgUrl + this.bgPictrue_rep[i] + '1000.jpg';this.bgPictrue.push(this.bgPictrue_str[i])}console.log(111,this.title)//重新创建一含对象的数组,把原来的各个属性的数组动态循环进新数组的对象里//console.log(11,this.pObj[0])for(let i=0;i<this.local.length;i++){var item = {//创建新数组的对象属性bgPictrue: '',local: '',price: '',title: '',id: 0}//对对象属性进行实例化赋值item.bgPictrue = this.bgPictrue[i];item.local = this.local[i];item.price = this.price[i];item.title = this.title[i];item.id = this.list[i].id;//动态循环进数组里//全部商品列表this.productList.push(item);}//2.给搜索提示数组赋值for(var i = 0;i<this.title.length;i++){this.states[i] = this.title[i];}this.searchList1=this.productList;})}// 自定义方法//1.改变页码触发的事件onPageChange(number: number){this.currentPage = number;}//2.关闭广告条public flag:boolean=false;close(){this.flag=true;}// 3.搜索框提示功能formatter = (result: string) => result.toUpperCase();search = (text$: Observable<string>) =>text$.pipe(debounceTime(200),distinctUntilChanged(),map(term => term === '' ? []: this.states.filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10)))//4.搜索框历史记录显示和数据持久化方法//4.1 搜索函数//在搜素框里调用的搜索函数doSearch(){//console.log("输入的搜索词:",this.model);if(this.model == ''){this.price_s=[];this.title_s=[];this.local_s=[];this.bgPictrue_s=[];this.bgPictrue_raw_s=[];this.bgPictrue_rep_s=[];this.bgPictrue_str_s=[];this.searchList1=[];this.searchList1=this.productList;}else{this.price_s=[];this.title_s=[];this.local_s=[];this.bgPictrue_s=[];this.bgPictrue_raw_s=[];this.bgPictrue_rep_s=[];this.bgPictrue_str_s=[];this.searchList1=[];var temp = {parameters: {keyWord: this.model}}return this.http.get(this.uri + 'Product/Search?keyWord=' + JSON.stringify(temp)).subscribe(search => {this.slist = search;//console.log('slist搜索数组:',this.slist)var re = /:/gi;for(var i = 0;i< this.slist.length;i++){//把json字符串转成对象this.pObj_s[i] = JSON.parse(this.slist[i].content.toString());this.title_s.push(this.pObj_s[i].supplierAds[0].m_title);this.price_s.push(this.pObj_s[i].supplierAds[0].m_price);this.local_s.push(this.pObj_s[i].supplierAds[0].m_supplierInfo.region);this.bgPictrue_raw_s.push(this.pObj_s[i].supplierAds[0].m_supplierOrderId);this.bgPictrue_rep_s[i] = this.bgPictrue_raw_s[i].replace(re,"-");this.bgPictrue_str_s[i] = this.awsImgUrl + this.bgPictrue_rep_s[i] + '1000.jpg';for(let i=0;i<this.local_s.length;i++){var item = {bgPictrue: '',local: '',price: '',title: '',id: 0}item.bgPictrue = this.bgPictrue_str_s[i];item.local = this.local_s[i];item.price = this.price_s[i];item.title = this.title_s[i];item.id = this.slist[i].id;this.searchList1.push(item);}}//console.log("输入的搜索词:",this.model);})}}//在历史记录里调用的搜索函数doSearch1(model:string){//console.log("输入的搜索词:", model);this.price_s=[];this.title_s=[];this.local_s=[];this.bgPictrue_s=[];this.bgPictrue_raw_s=[];this.bgPictrue_rep_s=[];this.bgPictrue_str_s=[];this.searchList1=[];var temp = {parameters: {keyWord: model}}return this.http.get(this.uri + 'Product/Search?keyWord=' + JSON.stringify(temp)).subscribe(search => {this.slist = search;//console.log('slist搜索数组:',this.slist)var re = /:/gi;for(var i = 0;i< this.slist.length;i++){//把json字符串转成对象this.pObj_s[i] = JSON.parse(this.slist[i].content.toString());this.title_s.push(this.pObj_s[i].supplierAds[0].m_title);this.price_s.push(this.pObj_s[i].supplierAds[0].m_price);this.local_s.push(this.pObj_s[i].supplierAds[0].m_supplierInfo.region);this.bgPictrue_raw_s.push(this.pObj_s[i].supplierAds[0].m_supplierOrderId);this.bgPictrue_rep_s[i] = this.bgPictrue_raw_s[i].replace(re,"-");this.bgPictrue_str_s[i] = this.awsImgUrl + this.bgPictrue_rep_s[i] + '.jpg';for(let i=0;i<this.local_s.length;i++){var item = {bgPictrue: '',local: '',price: '',title: '',id: 0}item.bgPictrue = this.bgPictrue_str_s[i];item.local = this.local_s[i];item.price = this.price_s[i];item.title = this.title_s[i];item.id = this.slist[i].id;this.searchList1.push(item);}}//console.log("输入的搜索词:", model);})}//4.2 存储函数doStorage(){//if语句检查输入的值在列表中是否存在,如果=-1说明不存在,则需要push进去if(this.historyList.indexOf(this.model)==-1 && this.model!=''){this.historyList.push(this.model);//理解push是什么意思}//自动清空搜索框里填入的内容this.model='';//获取属性的值console.log(this.model);//缓存数据,实现数据持久化this.storage.set('searchlist',this.historyList);}//4.3 接听回车事件,一按回车就把输入的内容push到列表中(此方法暂时不用)//了解对象怎么表示doAdd(e){if (e.keyCode==13) { //这里判断数据是否存在不可行,如果是一个对象,所以需要封装一个方法if(!this.historyListHasKeyword(this.historyList,this.model)){this.historyList.push(this.model)this.model='';}else{this.model='';}}//缓存数据,实现数据持久化this.storage.set('searchlist',this.historyList);//用到this一定要注意this的指向}//封装方法//如果数组里面有keyword返回true,否则返回falsehistoryListHasKeyword(historyList:any,model:any){//用异步存在问题,所以用另一种方法,用到for循环if (!model) return false;for (var i=0;i<historyList.length;i++) {if (historyList[i]==model) {return true;}}return false;}//4.4 删除单个历史记录函数deleteOneHistory(key){this.historyList.splice(key,1);//splice可以在数组里删除,增加,修改一个值。在这里表示从key位置往后删除一个值。this.storage.set('searchlist',this.historyList);}//4.5 一次性删除历史记录deleteHistory(){alert("删除全部历史记录?")this.historyList.splice(0,this.historyList.length);//splice可以在数组里删除,增加,修改一个值。在这里表示从key位置往后删除一个值。this.storage.set('searchlist',this.historyList);}}
CSS文件中:
/* 搜索框部分 *//* 设置搜索框的容器 */.search-bar{/* max-width: 400px; */height: 40px;background-color:#bbb;border: 2px solid rgb(0, 99, 186) ;}/* 搜索文本框 */.search-bar .searcch-inp{min-width: 100px;/* min-width: 150px; */height: 36px;/* 去掉边框 */border: none;color:rgb(121, 121,121);}/* 易出按钮 */.search-bar .out-btn{color: rgb(0, 99, 186);}/* 搜索按钮 */.search-bar .search-btn{min-width: 100px;/* min-width: 120px; */height: 38px;padding: 0;border: none;color: #fff;background:rgb(0, 99, 186);text-align: center;}.search-bar .search-btn:hover{background:rgb(4, 51, 92);}/* 搜索图标样式 */.search-bar .search-btn .material-icons{vertical-align:bottom;margin-bottom: -1px;margin-right: 7px;}/* 清除整个历史记录按钮样式*/.search-bar .delete-all-btn{float: right;margin-right: 20px;color: rgb(0, 99, 186);background-color: #fff;border: none;font-weight: bold;}/* 清除单个历史记录按钮样式*/.search-bar .delete-btn{float: right;margin-right: 20px;background-color: #fff;color: rgb(112, 112, 112);border: none;padding: 0;width: 20px;height: 20px;}.search-bar .delete-btn .material-icons{vertical-align:bottom;color: rgb(202,202, 202);}/* 下拉框的列表样式 */.search-bar li{color:rgb(121, 121,121);font-size: 13px;line-height: 25px;}.search-bar .history-title{color:rgb(0, 99, 186);font-size: 18px;font-weight: bold;margin-bottom: 10px;}.search-bar ul{margin-left: 20px;margin-top: 15px;}
二、参考资料:
1. input搜索框实时检索功能实现(超简单,核心原理请看思路即可):https://blog.csdn.net/qq_39974331/article/details/80410032
2. 前端和中后台的数据交互(用到json数据)
参考资料如下:
「前端」Angular 中的数据交互(get jsonp post):https://zhuanlan.zhihu.com/p/147852215
angular2——前后端交互:http://www.voidcn.com/article/p-aiycehtq-bms.html
3. 需要熟练使用API接口
4. 搜索框搜索时候的搜索值存储问题,以及需要点击两次搜索按钮才能在前端页面显示搜索的商品(存在异步问题)
参考资料——面试精选之Promise:https://juejin.cn/post/6844903625609707534
三、后续完善搜索框功能
1.前端搜索模糊搜索提示框:
功能参考链接:https://material.angular.io/components/autocomplete/examples
2.搜索框按照商品标题进行搜索:
使用indexof函数进行筛选;