先看效果
數據類型
模擬的數據層級結構
[
{
"name": "七年級",
"classes": [
{
"name": "1班"
},
{
"name": "2班"
},
{
"name": "3班"
}
]
},
{
"name": "八年級",
"classes": [
{
"name": "1班"
},
{
"name": "2班"
}
]
},
{
"name": "九年級",
"classes": [
{
"name": "1班"
},
{
"name": "2班"
},
{
"name": "3班"
},
{
"name": "4班"
}
]
}
]
data中的數據
data: {
rawData: [],
multiObjArray: [[], []],
multiIndex: [0, 0]
},
頁面
<picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiObjArray}}" range-key="{{'name'}}">
<view class="picker">
<text style="width:180rpx">班級</text>
{{multiObjArray[0][multiIndex[0]].name}},
{{multiObjArray[0][multiIndex[0]].classes[multiIndex[1]].name}}
</view>
</picker>
兩個主要方法
bindMultiPickerChange: function (e) {
console.log('picker改變,攜帶值爲', e.detail.value)
this.setData({
multiIndex: e.detail.value
})
} ,
bindMultiPickerColumnChange: function (e) {
console.log('修改的列爲', e.detail.column, ',值爲', e.detail.value);
if (e.detail.column == 0) {
this.setData({
'multiObjArray[1]': this.data.rawData[e.detail.value].classes,
});
}
},
/**
* 這裏主要設置初始化模擬數據,根據實際情況可以用接口返回的數據
*/
onLoad: function (options) {
let mockJson = [
{
name: "七年級", classes: [
{ name: "1班" }, { name: "2班" }, { name: "3班" }
]
},
{
name: "八年級", classes: [
{ name: "1班" }, { name: "2班" }
]
},
{
name: "九年級", classes: [
{ name: "1班" }, { name: "2班" }, { name: "3班" }, { name: "4班" }
]
}
];
this.setData({
rawData: mockJson,
'multiObjArray[0]': mockJson,
'multiObjArray[1]': mockJson[0].classes,
})
},
原理
最主要用的是multiObjArray數組和multiIndex下標,multiObjArray
記錄的是顯示的元素數組,第一維是年級信息,第二維是班級信息,第一維數據不需要更新只需要記錄選擇的位置即可,第二維需要根據第一維的變化進行變化,multiIndex
記錄的是multiObjArray
對應的下標,用來顯示和最後提交數據的時候用。
bindMultiPickerColumnChange 方法監聽到數據變化是個數組,第一個是列,第二個是行
由於只是兩級聯動,所以我們只需要關心列的變化即可,當列發生變化的時候從原始數據(原始的對象列表)根據序號找到對應的數據的孩子,賦值到二位數組的第二列。
列變化爲1的時候從rawData中找到rawData[1]的classes,賦值給二維數組的第二維
bindMultiPickerChange
當整個picker發生變化的時候重新記錄multiIndex的值