AngularJS中實現無限級聯動菜單(使用demo)
昨天沒來得及貼幾個使用demo,今天補上,供有興趣的同學參考 :)
1. 同步加載子選項demo
2. 異步加載子選項demo
3. 初始值回填demo
4. 倒金字塔依賴demo
directive的源代碼請移步上一個帖子:
http://www.cnblogs.com/front-end-ralph/p/5131687.html1. 同步加載子選項
在各聯動菜單加載之前,我們已經通過某種方式(比如后端渲染、api依賴、deferred依賴等等)拿到了渲染各級菜單所需的各種數據,我們只需要將該數據處理為
[{
text: 'some text',
value: 'some value'
},]
的形式,并封裝成數據源函數即可。以省-市聯動為例:
html部分:
注意第二個select中聲明了dependents="province",以此實現聯動
<select multi-level-select source="getProvinces" name="province" ng-model="form.province" empty="請選擇省份"></select> <select multi-level-select source="getCities" name="city" ng-model="form.city" empty="請選擇城市" dependents="province"></select>
controller部分:預處理數據,提供數據源函數
controller('myCtrl', ['$scope', function ($scope) {
// angular使用好習慣,將primitive值放到對象上
var form = {};
$scope.form = form;
var data = [{
name: '浙江',
id: 10,
cities: [{
name: '杭州',
id: 100
}, {
name: '寧波',
id: 101
}, {
name: '溫州',
id: 102
}]
}, {
name: '廣東',
id: 20,
cities: [{
name: '廣州',
id: 200
}, {
name: '深圳',
id: 201
}, {
name: '佛山',
id: 202
}]
}, {
name: '山東',
id: 30,
cities: [{
name: '濟南',
id: 301
}, {
name: '青島',
id: 302
}, {
name: '煙臺',
id: 303
}]
}];
var provinces = [];
var citiesLookup = {};
// 預處理,返回[{text: 'some text', value: 'some value'},]的數據格式
$.each(data, function (index, province) {
provinces.push({
text: province.name,
value: province.id
});
var cities = [];
$.each(province.cities, function (index, city) {
cities.push({
text: city.name,
value: city.id
});
});
citiesLookup[province.id] = cities;
});
$scope.getProvinces = function () {
return provinces;
};
$scope.getCities = function (values) {
return citiesLookup[values.province] || [];
};
}]); 2. 異步加載子選項demo
主要差異是數據源函數應該返回promise實例(AngularJS中使用$q即可)。為了演示方便,這里就不用$http了,除了預處理(由使用者自己的業務邏輯負責)外,完全一樣。
和上一個例子非常相似,只需要將兩個數據源函數修改為:
$scope.getProvinces = function () {
return $q(function (resolve) {
// 異步時應返回promise,這里就不用http了,除了預處理(由使用者自己的業務邏輯負責)外,完全一樣
// 如果需要緩存,也請在這里自己負責
$timeout(function () {
resolve(provinces);
}, 100);
});
};
$scope.getCities = function (values) {
return $q(function (resolve) {
$timeout(function () {
resolve(citiesLookup[values.province] || []);
}, 100);
});
}; 3. 初始值回填因為在開發初期這個需求就很明確了,所以使用上不需要做額外的工作,如果有初始值,只需要在controller中為其賦值即可:
// angular使用好習慣,將primitive值放到對象上
var form = {};
$scope.form = form;
form.province = 30;
form.city = 301; 4. 倒金子塔依賴
依賴聲明是通過由逗號分割的字符串的形式完成的,使用上非常方便。
設想以下的場景:
教務處需要學生對課程進行評價,學生先選擇周幾,再選擇時間,然后再選擇具體的課程下拉框
周幾和時間之間互不依賴,課程下拉框同時依賴于周幾和時間,換言之,一旦周幾和時間中的任意一個改變,課程下拉框就應該更新。
html部分:
注意第三個select的dependents屬性是day,hour,即同時依賴于day和hour
<select multi-level-select source="getDays" name="day" ng-model="form.day" empty="請選擇周幾"></select> <select multi-level-select source="getHours" name="hour" ng-model="form.hour" empty="請選擇時間"></select> <select multi-level-select source="getCourses" name="course" ng-model="form.course" empty="請選擇課程" dependents="day,hour"></select>
controller部分:和前面的例子類似,沒有什么特殊的,預處理數據并提供數據源函數即可。
controller('myCtrl', function ($scope) {
var form = {};
$scope.form = form;
$scope.getDays = function () {
var days = '一二三'.split('');
days.forEach(function (item, index) {
days[index] = {
text: '星期' + item,
value: '星期' + item
};
});
return days;
};
$scope.getHours = function () {
return [{
text: '09:00-12:00',
value: '1'
}, {
text: '14:00-17:00',
value: '2'
}];
};
var courses = {
'星期一': {
'1': [{
value: '數學',
text: '數學'
}, {
value: '精讀',
text: '精讀'
}],
'2': [{
value: '足球',
text: '足球'
}]
},
'星期二': {
'1': [{
value: '聽力',
text: '聽力'
}],
'2': [{
value: '數學',
text: '數學'
}]
},
'星期三': {
'1': [{
value: '計算機',
text: '計算機'
}],
'2': [{
value: '游泳',
text: '游泳'
}, {
value: '古漢語',
text: '古漢語'
}]
},
};
$scope.getCourses = function (values) {
if (!values.day || !values.hour) {
return [];
}
return courses[values.day][values.hour];
};
}); 有興趣的同學如果需要其他應用場景下的demo也可以告訴我 :)