利用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
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。