ionic3 城市索引

效果图:

 

未处理城市数据:

 

 

html部分:

header 搜索栏部分:

<ion-header>
    <ion-navbar>
    </ion-navbar>
    <ion-searchbar class="searchBox" placeholder="请输入城市拼音或汉字" (ionInput)="getItems($event)"></ion-searchbar>

    <div class="flexContainer current align_center">
    <div class="f1 city">
        目前所选定位:<span #containermap  (tap)="citySelect(curPos)">{{curPos}}</span>
    </div>
    <div class="flex">
        <div class="row_end reset" (tap)="getPosition()">重新定位 </div>
        <div class="resetPos" (tap)="citySelect(resetPosition)">{{resetPosition}}</div>
    </div>
    

    </div>
</ion-header>

content部分: 主要是显示全部城市列表和经过搜索后过滤出来的列表

<ion-content>
    <div class="citiesBox">
        <div class="left_city" #left_city>
            <div class="recent_title" *ngIf="cacheSearchCity">最近访问</div>
            <div class="recent" *ngIf="cacheSearchCity">
                <span *ngFor="let his of cacheSearchCity"  tappable (click)="citySelect(his)">{{his.name}}</span>
            </div>

            <div class="recent_title">已入驻城市</div>
            <div #list>
                <ion-list >
                    <!--搜索过滤的数组-->
                    <ion-item-sliding *ngFor="let c of filteredCities">
                        <ion-item  tappable (click)="citySelect(c)">{{c.name}}</ion-item>
                    </ion-item-sliding>
    
                    <!--全部城市数组-->
                    <ion-item-group *ngFor="let item of cities" #cityGroup>
                        <ion-item-divider>
                            <ion-label class="index_title">{{item.index}}</ion-label>
                        </ion-item-divider>
                        <ion-item *ngFor="let c of item.cities" (tap)="citySelect(c)">{{c.name}}</ion-item>
                    </ion-item-group>
                </ion-list>
            </div>
        </div>
    </div>
</ion-content>

footer部分: A~Z的字母索引

<ion-footer>
    <div id="indexs-bar"  class="right_indexes">
        <div class="index-bar" 
        *ngFor="let item of rightIndexes;let i = index"
        (touchstart)="IndexTouchStart($event)"
        id="item"
        >{{item}}</div>
    </div>
    
</ion-footer>

 

 

ts部分:

import { Component , ViewChild ,ElementRef , ViewChildren, Renderer2} from '@angular/core';
import { IonicPage, NavController, NavParams , Content, Events } from 'ionic-angular';
import { Storage } from '@ionic/storage';
import { NativeService } from '../../services/native.service';
import { RestService } from '../../services/rest.services';
import Bscroll from 'better-scroll';
 
@IonicPage()
@Component({
  selector: 'page-location',
  templateUrl: 'location.html',
})
export class LocationPage{
 
  @ViewChild(Content) content: Content;
  @ViewChildren('cityGroup') cityGroup;
  @ViewChildren('list') list:ElementRef;
  @ViewChild("containermap") containermap: ElementRef;

  
  curPos:string = ""; //当前定位
  cities: Array<any> = []; //城市数组
  oriCities: Array<any> = []; //城市数组--接口返回值

  filteredCities: Array<any> = []; //过滤城市数组

  cacheSearchCity:Array<any>=[];//历史搜索

  resetPosition:string="";

  public scroll;

    //右侧字母排序数组
    rightIndexes = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
    constructor(
        public navCtrl: NavController, 
        public navParams: NavParams,
        public nativeService: NativeService,
        public storage: Storage,
        public ele: ElementRef,
        public r2: Renderer2,
        public restService: RestService,
        public events: Events,
    ) {
        this.curPos = this.navParams.data.curPosition;
        this.storage.get("city_history").then(cacheCity=>{
          this.cacheSearchCity = cacheCity;
        });
        
    
    }

    
 
    ionViewDidLoad() {
        this.storage.get("citydata")
        .then(data=>{
            if(data){
                this.cities = this.getGroupCities(data);
                this.oriCities = data;
            }else{
              this.restService.locationCity()
                .subscribe((citisArr:any)=>{
                  console.log(citisArr)
                  this.oriCities = citisArr.body.cities;
                  this.cities = this.getGroupCities(this.oriCities);
                  this.storage.set("citydata",this.oriCities);
                })
            }
        })
    }

    ionViewDidEnter(){
      this.scroll = new Bscroll(this.content.getNativeElement().children[1]);
    }
  

    /*
    * 重新定位
    * @memberof LocationPage
    */
  getPosition(){
    this.resetPosition = "定位中...";
    this.getResetPos().then((data:string)=>{
      this.resetPosition = data;
    },(err)=>{
      this.resetPosition = "定位失败";
    })
  }

  getResetPos(){
    return new Promise((resolve,reject)=>{
      (<any>window).GaoDe.getCurrentPosition((successData)=>{
        resolve(successData.city)
      }, (faileData)=>{
        reject("定位失败");
      });
    })
  }
    
    IndexTouchStart(ev){
      this.alphabetMove(ev, true);
    }

 
    /**
     *
     * 滚动效果
     * @param {*} e
     * @param {*} move
     * @returns
     * @memberof LocationPage
     */
    alphabetMove(e, move) {
        let currentItem;
        currentItem = e.target;
        if (!currentItem || currentItem.className.indexOf('index-bar') < 0) return;
        if (move) {
            let index = this.rightIndexes.join('').indexOf(currentItem.innerText);
            let scrollHeight = this.cityGroup._results[index].nativeElement.offsetTop;
            this.content.scrollTo(this.content.contentTop,scrollHeight-5,300);
        }
    }


    
    
   
 
    /**
     * 城市分组排序
     */
    getGroupCities(cities){
        var group = [];
        this.rightIndexes.forEach(c => {
            let cCities = cities.filter(cityItem=>cityItem.index===c);
            group.push({
                index:c,
                cities:cCities
            })
        });
        return group;
    }
 
   
    /**
     * 点击选择搜索的城市
     * @param city 选择的城市
     */
    citySelect(city) {
      this.storage.get("city_history").then((cities:any)=>{
        if(cities == null) cities = [];
        cities.forEach((element,index) => {
          if(city.name == element.name){
            cities.splice(index,1);
          }
        });
        if(cities.length >=3){
          cities.pop();
          cities.unshift(city);
          this.storage.set("city_history",cities);
          this.cacheSearchCity = cities;
        }else{
          cities.unshift(city);
          this.storage.set("city_history",cities);
          this.cacheSearchCity = cities;
        }
        this.navCtrl.pop();
        this.events.publish("select_postion",city);
      })

    }
 
 
    /**
     *城市搜索
     *
     * @memberof LocationPage
     */
    getItems(ev){
        var newVal = ev.target.value;
        if (newVal) {
            this.filteredCities = this.filterCities(newVal);
        }
        else {
            this.filteredCities = [];
        }
        this.content.scrollToTop(500);
    }
 
 
    /**
     *过滤符合条件的城市
     *
     * @param {*} val
     * @memberof LocationPage
     */
    filterCities(val){
        var filterCities = [];
        this.oriCities.filter(item=>{
            if(item.name.indexOf(val)>-1){
                filterCities.push(item);
            }
        })
        return filterCities;
    }

    /**
     * 选择当前定位,返回首页
     */
    comfirmCurPostion(){
      this.navCtrl.pop();
    }
    
}

css:

page-location {
    background: transparent;
    .searchbar-ios.searchBox{
        background: #fff;
        border: 0;
        input{
            background-color: #f3f3f3 ;
            border-radius: .5rem ;
        }
    }
    .searchbar-ios.searchBox .searchbar-search-icon{
        top: .2rem ;
        width: .4rem ;
        height: .3rem ;
        background-size: .4rem .36rem ;
    }

    
    .reset {
        background: url("../assets/imgs/zhinz.png") #fff right center no-repeat;
        background-size: .24rem;
        padding-right: .3rem;
        color: #999;
        font-size: .26rem;
        margin: .2rem 0 .05rem 0;
    }

    .resetPos{
        margin-left: 30%;
    }
    .current {
        padding: .22rem;
        background-color: #fff;
        min-height: .88rem;
        .city {
            font-size: .26rem;
            span {
                font-size: .26rem;
                font-weight: 200;
            }
        }
    }
    
    .recent_title {
        height: (.68rem);
        line-height: (.68rem);
        font-size:  .26rem;
        background-color: #f3f3f3;
        padding-left: .22rem;
    }
    .recent {
        display: flex;
        height: .88rem;
        justify-content: center;
        align-items: center;
        span {
            flex: 1;
            text-align: center;
            font-size: .24rem;
            font-weight: 200;
            display: inline-block;
        }
    }
 
 
 
    .citiesBox{
        position: absolute;
        top: 0;
        left: 0;
        right: .6rem;
        overflow-y: scroll;
        .left_city{
            overflow: visible;
        }
    }  
    
    //A-Z
    .right_indexes{
        position: absolute;
        top: 0;
        right: 0;
        width: .6rem;
        text-align: center;
        color: #cb9e5e;
        div{
            cursor: pointer;
            font-size: .3rem;
            line-height: 1.2;
        }
    }
    
 
    
    /* 列表 */
    .item-divider-ios{
        background: #fff;
    }
    
 
    .item-block{
        min-height: inherit;
    }
 
    .label-ios{
        font-size: .26rem;
    }
 
    .fixed-content,.scroll-content{
        margin-bottom: 0 !important;
    }
    ion-footer{
        top: (3rem);
        right: 0;
        left: auto;
        width:.6rem;
    }
}

over~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值