利用Ionic2 + angular4实现一个地区选择组件
前言
本文主要给大家介绍的是关于利用Ionic2+angular4实现一个地区选择组件的相关内容,为什么会有这篇文章?主要是因为最近在项目重构的过程中,发现之前用mobiscroll写的地区选择指令在angular2中很难重用(毕竟是用typeScript)。于是就萌生了自己写一个组件的想法。
想和之前一样基于mobiscroll去写,但是发现非常耗费精力,于是某日万般无奈这下搜了一下相关的组件,不出所料已经有人写了。https://www.npmjs.com/package...但是此组件并不符合我的要求。我不是单纯的选择省市区,还可能是选择省市或者省。于是参照此项目基于ionic2的picker写了一个公用组件。下面话不多说了,感兴趣的朋友们下面来一起看看详细的介绍:
具体代码如下:
AreasSelect.ts
import{PickerController}from"ionic-angular"; import{Component,EventEmitter,Output,Input}from"@angular/core"; import{areasList}from"../../datasource/areas"; @Component({ selector:'areas-select', templateUrl:'areasSelect.com.html', }) exportclassAreasSelect{ constructor(protectedPicker:PickerController){ } privatepicker; privateprovinceCol=0;//省列 privatecityCol=0;//市列 privateregionCol=0;//区列 privatepickerColumnCmps;//picker纵列数据实例 privateisOpen=false;//是否被创建 privatepickerCmp;//picker实例 privatevalue='';//选中后的数据 @Input()citiesData=areasList;//地区数据(默认为areas.ts的数据) @Input()cancelText='关闭';//关闭按钮文本 @Input()doneText='完成';//完成按钮文本 @Input()separator='';//数据衔接模式 @Input()level=3;//等级设置最高为三级 /** *关闭时触发的事件 *没有值返回 *@type{EventEmitter} */ @Output()cancel:EventEmitter=newEventEmitter();//关闭事件 /** *完成时触发的事件 *返回值为obj *obj={data:object,value:string}data为对应的省市区和编码 *@type{EventEmitter} */ @Output()done:EventEmitter =newEventEmitter();//完成事件 /** *打开地区选择器 *基本思路 *1.创建picker *2.先把数据处理成省市区分开的数组 *3.将数据以列的形式给到picker *4.设置数据显示样式(picker) *5.生成picker */ privateopen(){ letpickerOptions={ buttons:[ { text:this.cancelText, role:'cancel', handler:()=>{ this.cancel.emit(null); } }, { text:this.doneText, handler:(data)=>{ this.onChange(data); this.done.emit({ data:data, value:this.value }); } } ] }; this.picker=this.Picker.create(pickerOptions); this.generate();//加载 this.validate(this.picker);//渲染 this.picker.ionChange.subscribe(()=>{ this.validate(this.picker); }); //生成 this.picker.present(pickerOptions).then(()=>{ this.pickerCmp=this.picker.instance; this.pickerColumnCmps=this.pickerCmp._cols.toArray(); this.pickerColumnCmps.forEach(function(col){ returncol.lastIndex=-1; }); }); this.isOpen=true; this.picker.onDidDismiss(function(){ this.isOpen=false; }); } /**对数据进行处理,并移交给picker * */ privategenerate(){ letvalues=this.value.toString().split(this.separator); //Addprovincedatatopicker letprovinceCol={ name:'province', options:this.citiesData.map(function(province){ return{text:province.name,value:province.code,disabled:false}; }), selectedIndex:0 }; letprovinceIndex=this.citiesData.findIndex(function(option){ returnoption.name==values[0]; }); provinceIndex=provinceIndex===-1?0:provinceIndex; provinceCol.selectedIndex=provinceIndex; this.picker.addColumn(provinceCol); //Addcitydatatopicker letcityColData=this.citiesData[provinceCol.selectedIndex].children; letcityCol; if(this.level>=2){ cityCol={ name:'city', options:cityColData.map(function(city){ return{text:city.name,value:city.code,disabled:false}; }), selectedIndex:0 }; letcityIndex=cityColData.findIndex(function(option){ returnoption.name==values[1]; }); cityIndex=cityIndex===-1?0:cityIndex; cityCol.selectedIndex=cityIndex; this.picker.addColumn(cityCol); } //Addregiondatatopicker letregionData,regionCol; if(this.level===3){ regionData=this.citiesData[provinceCol.selectedIndex].children[cityCol.selectedIndex].children; regionCol={ name:'region', options:regionData.map(function(city){ return{text:city.name,value:city.code,disabled:false}; }), selectedIndex:0 }; letregionIndex=regionData.findIndex(function(option){ returnoption.name==values[2]; }); regionIndex=regionIndex===-1?0:regionIndex; regionCol.selectedIndex=regionIndex; this.picker.addColumn(regionCol); } this.divyColumns(this.picker); } /**设置数据显示样式 *@parampicker */ privatedivyColumns(picker){ letpickerColumns=this.picker.getColumns();//获取列数据 letcolumns=[]; pickerColumns.forEach(function(col,i){ columns.push(0); col.options.forEach(function(opt){ if(opt&&opt.text&&opt.text.length>columns[i]){ columns[i]=opt.text.length; } }); }); if(columns.length===2){ letwidth=Math.max(columns[0],columns[1]); pickerColumns[0].align='right'; pickerColumns[1].align='left'; pickerColumns[0].optionsWidth=pickerColumns[1].optionsWidth=width*17+"px"; } elseif(columns.length===3){ letwidth=Math.max(columns[0],columns[2]); pickerColumns[0].align='right'; pickerColumns[1].columnWidth=columns[1]*33+"px"; pickerColumns[0].optionsWidth=pickerColumns[2].optionsWidth=width*17+"px"; pickerColumns[2].align='left'; } } /** *验证数据 *@parampicker */ privatevalidate(picker){ let_this=this; letcolumns=picker.getColumns(); letprovinceCol=columns[0]; letcityCol=columns[1]; letregionCol=columns[2]; if(cityCol&&this.provinceCol!=provinceCol.selectedIndex){ cityCol.selectedIndex=0; letcityColData=this.citiesData[provinceCol.selectedIndex].children; cityCol.options=cityColData.map(function(city){ return{text:city.name,value:city.code,disabled:false}; }); if(this.pickerColumnCmps&&cityCol.options.length>0){ setTimeout(function(){ return_this.pickerColumnCmps[1].setSelected(0,100); },0); } } if(regionCol&&(this.cityCol!=cityCol.selectedIndex||this.provinceCol!=provinceCol.selectedIndex)){ letregionData=this.citiesData[provinceCol.selectedIndex].children[cityCol.selectedIndex].children; regionCol.selectedIndex=0; regionCol.options=regionData.map(function(city){ return{text:city.name,value:city.code,disabled:false}; }); if(this.pickerColumnCmps&®ionCol.options.length>0){ setTimeout(function(){ return_this.pickerColumnCmps[2].setSelected(0,100); },0); } } this.provinceCol=provinceCol.selectedIndex; this.cityCol=cityCol?cityCol.selectedIndex:0; this.regionCol=regionCol?regionCol.selectedIndex:0; } /** *设置value *@paramnewData */ privatesetValue(newData){ if(newData===null||newData===undefined){ this.value=''; } else{ this.value=newData; } } /** *获取value值 *@returns{string} */ privategetValue(){ returnthis.value; } /** *改变value值的显示 *@paramval */ privateonChange(val){ this.setValue(this.getString(val)); } /** *获取当前选择的地区数据 *@paramnewData *@returns{string} */ privategetString(newData){ if(newData['city']){ if(newData['region']){ return""+newData['province'].text+this.separator+(newData['city'].text||'')+this.separator+(newData['region'].text||''); } return""+newData['province'].text+this.separator+(newData['city'].text||''); } return""+newData['province'].text; } }
areasSelect.com.html
其实是不需要对应的template的,但是为了能和父级传参,这里创建了一个空的template
具体用法:
在需要用到的页面调用
test.page.html
地区选择
test.page.ts
import{Component,ElementRef,Injector,ViewChild}from"@angular/core"; import{BasePage}from"../base.page"; @Component({ templateUrl:'test.page.html', styles:[] }) exportclassTestPageextendsBasePage{ constructor(protectedrt:ElementRef,protectedij:Injector){ super(rt,ij); } @ViewChild('areasSelect')areasSelect; showAreasSelect(){ this.areasSelect.open(); } done(data){ this.showAlert(JSON.stringify(data)); } closeSelect(){ this.showAlert('youclickclose'); } }
没有地区数据json或ts的文件可以去这里获取:http://xiazai.jb51.net/201707/yuanma/regional_data(jb51.net).rar
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。