Angular.JS实现无限级的联动菜单(使用demo)


Posted in Javascript onFebruary 08, 2017

前言

之前给大家介绍过一篇关于AngularJS中实现无限级联动菜单的文章,但没来得及和大家分享使用的示例,下面这篇文章就来给大家分享下几个使用的demo。

文中包括demo如下:

1. 同步加载子选项demo

2. 异步加载子选项demo

3. 初始值回填demo

4. 倒金字塔依赖demo

注意:在阅读本文前请先移步上一篇文章:https://3water.com/article/78126.htm

1. 同步加载子选项

在各联动菜单加载之前,我们已经通过某种方式(比如后端渲染、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];
 };
});

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
JavaScript this 深入理解
Jul 30 Javascript
学习ExtJS table布局
Oct 08 Javascript
Javascript 去除数组的重复元素
May 04 Javascript
在JavaScript中构建ArrayList示例代码
Sep 17 Javascript
Node.js实现批量去除BOM文件头
Dec 20 Javascript
javascript中Object使用详解
Jan 26 Javascript
jquery+ajax实现注册实时验证实例详解
Dec 08 Javascript
基于BootStrap实现局部刷新分页实例代码
Aug 08 Javascript
JS改变页面颜色源码分享
Feb 24 Javascript
解决angular2 获取到的数据无法实时更新的问题
Aug 31 Javascript
使用vue2.6实现抖音【时间轮盘】屏保效果附源码
Apr 24 Javascript
vue修改Element的el-table样式的4种方法
Sep 17 Javascript
基于JS实现二维码图片固定在右下角某处并跟随滚动条滚动
Feb 08 #Javascript
jQuery实现级联下拉框实战(5)
Feb 08 #Javascript
webpack入门+react环境配置
Feb 08 #Javascript
JavaScript实现鼠标点击导航栏变色特效
Feb 08 #Javascript
jQuery实现优雅的弹窗效果(6)
Feb 08 #Javascript
JavaScript中的子窗口与父窗口的互相调用问题
Feb 08 #Javascript
深入理解js中的加载事件
Feb 08 #Javascript
You might like
Windows下部署Apache+PHP+MySQL运行环境实战
2012/08/31 PHP
Thinkphp将二维数组变为标签适用的一维数组方法总结
2014/10/30 PHP
ThinkPHP查询语句与关联查询用法实例
2014/11/01 PHP
codeigniter显示所有脚本执行时间的方法
2015/03/21 PHP
php 参数过滤、数据过滤详解
2015/10/26 PHP
thinkPHP3.2.3结合Laypage实现的分页功能示例
2018/05/28 PHP
php 将json格式数据转换成数组的方法
2018/08/21 PHP
Thinkphp5 自定义上传文件名的实现方法
2019/07/23 PHP
简介JavaScript中toUpperCase()方法的使用
2015/06/06 Javascript
js判断手机号是否正确并返回的实现代码
2017/01/17 Javascript
深入理解Javascript中的作用域链和闭包
2017/04/25 Javascript
Bootstrap里的文件分别代表什么意思及其引用方法
2017/05/01 Javascript
jQuery实现滚动到底部时自动加载更多的方法示例
2018/02/18 jQuery
Vuex中mutations与actions的区别详解
2018/03/01 Javascript
Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
2018/04/09 Javascript
解决JavaScript中0.1+0.2不等于0.3问题
2018/10/23 Javascript
Vue指令指令大全
2019/02/09 Javascript
详解vue-cli3多环境打包配置
2019/03/28 Javascript
vue将后台数据时间戳转换成日期格式
2019/07/31 Javascript
JavaScript冒泡算法原理与实现方法深入理解
2020/06/04 Javascript
vuejs element table 表格添加行,修改,单独删除行,批量删除行操作
2020/07/18 Javascript
[59:42]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
用Python制作在地图上模拟瘟疫扩散的Gif图
2015/03/31 Python
python批量添加zabbix Screens的两个脚本分享
2017/01/16 Python
Python3 操作 MySQL 插入一条数据并返回主键 id的实例
2020/03/02 Python
北美大型运动类产品商城:Champs Sports
2017/01/12 全球购物
屈臣氏官方旗舰店:亚洲享负盛名的保健及美妆零售商
2019/03/15 全球购物
strstr()的简单实现
2013/09/26 面试题
数据库什么时候应该被重组
2012/11/02 面试题
公务员转正鉴定材料
2014/02/11 职场文书
学党史心得体会
2014/09/05 职场文书
解除劳动关系协议书2篇
2014/11/28 职场文书
销售人员管理制度
2015/08/06 职场文书
利用Python判断你的密码难度等级
2021/06/02 Python
MySQL query_cache_type 参数与使用详解
2021/07/01 MySQL
Python使用plt.boxplot()函数绘制箱图、常用方法以及含义详解
2022/08/14 Python