Dropdown组件
自己封装的一个简单的dropdown的组件
.ui-dropdown {
position:relative;
display:inline-block;
*display:inline;
*zoom:1;
width:162px;
border-radius:3px;
text-align:left;
font:12px/28px tahoma,arial,Hiragino Sans GB,WenQuanYi Micro Hei,'\5FAE\8F6F\96C5\9ED1','\5B8B\4F53',sans-serif;
vertical-align:top
}
.ui-dropdown-bd {
display:none;
top:31px;
left:0;
min-width:calc(100% - 2px);
max-height:346px;
overflow-y:auto;
overflow-x:hidden;
_overflow:auto;
position:absolute;
padding-bottom:8px;
background-color:#fff;
border:1px solid #848484;
border-radius:0 0 3px 3px;
-webkit-box-shadow:0 0 0 2px #f7f7f7;
box-shadow:0 0 0 2px #f7f7f7
}
.ui-dropdown-bd-right {
left:auto;
right:0
}
.ui-dropdown-bd .selected a,.ui-dropdown-bd .selected a:hover,.ui-dropdown-bd .selected a:active {
background-color:#f10180;
color:#fff
}
.ui-dropdown-bd a {
display:block;
padding:0 10px;
text-overflow:ellipsis;
white-space:nowrap;
overflow:hidden;
color:#333;
text-decoration:none;
*zoom:1
}
.ui-dropdown-bd a:hover {
color:#666;
text-decoration:none;
background-color:#ededed
}
.ui-dropdown-bd a:active {
background-color:#f10180;
color:#fff
}
.ui-dropdown-hd {
position:relative;
z-index:2;
padding:0 10px;
border:1px solid #b3b3b3;
border-radius:3px;
background-color:#fff;
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
cursor:pointer;
*zoom:1
}
.ui-dropdown-hd:hover {
border-color:#949494
}
.ui-dropdown-hd:hover .vipFont {
color:#949494
}
.ui-dropdown-hd .vipFont {
position:absolute;
right:7px;
color:#b3b3b3;
-webkit-transition:-webkit-transform .2s;
transition:transform .2s;
line-height:1
}
.ui-dropdown-hd .i-arrow-down {
top:7px
}
.ui-dropdown-hd .i-arrow-up {
visibility:hidden;
-webkit-transform:rotate(-180deg);
-ms-transform:rotate(-180deg);
transform:rotate(-180deg);
top:6px
}
.ui-dropdown-current {
display:block;
zoom:1;
color:#999;
line-height:30px;
text-decoration:none;
font-size:14px;
margin-right:10px;
text-overflow:ellipsis;
white-space:nowrap;
overflow:hidden
}
.ui-dropdown-current:hover {
color:#999;
text-decoration:none
}
.ui-dropdown-tips {
padding:12px 0 4px 10px;
line-height:20px;
color:#ed1616
}
.ui-dropdown .ui-dropdown-menu .ui-dropdown-loading {
float:none;
width:auto;
padding-top:10px;
line-height:80px;
text-align:center;
font-size:14px;
color:#333
}
.ui-dropdown .ui-dropdown-menu .ui-dropdown-loading .ii-loading-pink-16x16,.ui-dropdown .ui-dropdown-menu .ui-dropdown-loading .ii-loading-pink-24x24,.ui-dropdown .ui-dropdown-menu .ui-dropdown-loading .ii-loading-pink-32x32 {
vertical-align:middle;
margin-right:12px
}
.ui-dropdown .ui-dropdown-menu .ui-dropdown-loading .text {
display:inline-block;
vertical-align:middle
}
.ui-dropdown-col-2,.ui-dropdown-col-3,.ui-dropdown-col-4 {
width:115px
}
.z-ui-dropdown-open .ui-dropdown-col-2 .ui-dropdown-hd,.z-ui-dropdown-open .ui-dropdown-col-3 .ui-dropdown-hd,.z-ui-dropdown-open .ui-dropdown-col-4 .ui-dropdown-hd {
border-bottom:0;
padding-bottom:1px
}
.ui-dropdown-col-2 .ui-dropdown-bd,.ui-dropdown-col-3 .ui-dropdown-bd,.ui-dropdown-col-4 .ui-dropdown-bd {
padding-top:8px
}
.ui-dropdown-col-2 .ui-dropdown-tips,.ui-dropdown-col-3 .ui-dropdown-tips,.ui-dropdown-col-4 .ui-dropdown-tips {
padding-top:0
}
.ui-dropdown-col-2 .ui-dropdown-menu,.ui-dropdown-col-3 .ui-dropdown-menu,.ui-dropdown-col-4 .ui-dropdown-menu {
padding:0 5px
}
.ui-dropdown-col-2 .ui-dropdown-menu li,.ui-dropdown-col-3 .ui-dropdown-menu li,.ui-dropdown-col-4 .ui-dropdown-menu li {
float:left;
_overflow:hidden
}
.ui-dropdown-col-2 .ui-dropdown-menu li a,.ui-dropdown-col-3 .ui-dropdown-menu li a,.ui-dropdown-col-4 .ui-dropdown-menu li a {
_width:83px;
padding:0 0 0 5px;
margin:0 5px 2px
}
.ui-dropdown-col-2 .ui-dropdown-bd {
width:190px
}
.ui-dropdown-col-2 .ui-dropdown-menu li {
width:50%
}
.ui-dropdown-col-3 .ui-dropdown-bd {
width:280px
}
.ui-dropdown-col-3 .ui-dropdown-menu li {
width:33%
}
.ui-dropdown-col-4 .ui-dropdown-bd {
width:370px
}
.ui-dropdown-col-4 .ui-dropdown-menu li {
width:25%
}
.ui-dropdown-float {
line-height:26px;
width:120px
}
.ui-dropdown-float:hover,.ui-dropdown-float-hover {
z-index:100
}
.ui-dropdown-float:hover .ui-dropdown-hd .vipFont,.ui-dropdown-float-hover .ui-dropdown-hd .vipFont {
color:#848484;
line-height:1
}
.ui-dropdown-float:hover .ui-dropdown-hd .i-arrow-up,.ui-dropdown-float-hover .ui-dropdown-hd .i-arrow-up {
visibility:visible;
-webkit-transform:rotate(0deg);
-ms-transform:rotate(0deg);
transform:rotate(0deg)
}
.ui-dropdown-float:hover .ui-dropdown-hd .i-arrow-down,.ui-dropdown-float-hover .ui-dropdown-hd .i-arrow-down {
visibility:hidden;
-webkit-transform:rotate(180deg);
-ms-transform:rotate(180deg);
transform:rotate(180deg)
}
.ui-dropdown-float:hover .ui-dropdown-bd,.ui-dropdown-float-hover .ui-dropdown-bd {
display:block
}
.ui-dropdown-float:hover .ui-dropdown-current,.ui-dropdown-float-hover .ui-dropdown-current {
color:#333
}
.ui-dropdown-float .ui-dropdown-current {
display:inline-block;
padding-right:16px;
margin-right:0;
color:#666;
font-size:12px
}
.ui-dropdown-float .ui-dropdown-current:hover {
color:#333
}
.ui-dropdown-float .ui-dropdown-hd {
border:0 none;
background:0
}
.ui-dropdown-float .ui-dropdown-hd .vipFont {
right:auto;
margin-left:-16px
}
.ui-dropdown-float .ui-dropdown-bd {
top:0;
max-height:312px;
padding-top:30px;
border-radius:0;
border-color:#cbcaca
}
.ui-dropdown-float .ui-dropdown-bd a {
color:#666
}
.ui-dropdown-float .ui-dropdown-bd a:hover,.ui-dropdown-float .ui-dropdown-bd a:active {
background:0;
color:#f10180
}
.ui-dropdown-float .ui-dropdown-bd .selected a,.ui-dropdown-float .ui-dropdown-bd .selected a:hover,.ui-dropdown-float .ui-dropdown-bd .selected a:active {
background:0;
color:#f10180
}
.ui-dropdown-float .ui-dropdown-menu .ui-dropdown-loading {
line-height:50px;
font-size:12px
}
.z-ui-dropdown-selected .ui-dropdown-current,.z-ui-dropdown-selected .ui-dropdown-current:hover {
color:#333
}
.z-ui-dropdown-disable .ui-dropdown-hd {
background-color:#f0efef;
color:#999;
cursor:not-allowed
}
.z-ui-dropdown-disable .ui-dropdown-hd:hover .vipFont {
color:#b3b3b3
}
.z-ui-dropdown-disable .ui-dropdown-current,.z-ui-dropdown-disable .ui-dropdown-current:hover {
color:#999;
cursor:not-allowed
}
.z-ui-dropdown-open {
z-index:100;
-webkit-box-shadow:0 0 0 2px rgba(153,153,153,.08);
box-shadow:0 0 0 2px rgba(153,153,153,.08)
}
.z-ui-dropdown-open .ui-dropdown-hd {
border-radius:3px 3px 0 0;
border-color:#848484;
border-bottom-color:#dcdada
}
.z-ui-dropdown-open .ui-dropdown-hd .vipFont {
color:#848484
}
.z-ui-dropdown-open .ui-dropdown-hd .i-arrow-up {
visibility:visible;
-webkit-transform:rotate(0deg);
-ms-transform:rotate(0deg);
transform:rotate(0deg)
}
.z-ui-dropdown-open .ui-dropdown-hd .i-arrow-down {
visibility:hidden;
-webkit-transform:rotate(180deg);
-ms-transform:rotate(180deg);
transform:rotate(180deg)
}
.z-ui-dropdown-open .ui-dropdown-bd {
display:block
}
function BindDropdownEvent(elements, callback) {
$('.ui-dropdown-hd', elements).unbind().click(function() {
var element = $(this),
uiDropdown = element.parent('.ui-dropdown');
if (element.hasClass('z-ui-dropdown-disable')) {
return false;
}
if (uiDropdown.hasClass('z-ui-dropdown-open')) {
uiDropdown.removeClass('z-ui-dropdown-open');
} else {
$('.ui-dropdown').not(uiDropdown).removeClass('z-ui-dropdown-open');
$('.multi-dropdown').not(uiDropdown).removeClass('z-ui-dropdown-open');
uiDropdown.addClass('z-ui-dropdown-open');
$(document).one('click', function() {
uiDropdown.removeClass('z-ui-dropdown-open');
return false;
});
}
return false;
});
$('.ui-dropdown-bd', elements).unbind().each(function() {
var element = $(this),
uiDropdown = element.parent('.ui-dropdown'),
liList = element.find('li'),
uiDropdownCurrent = uiDropdown.find('.ui-dropdown-current');
liList.click(function() {
var subElement = $(this),
item = subElement.find('a');
liList.removeClass('selected');
subElement.addClass('selected');
var selectValue = item.attr('value');
uiDropdownCurrent.attr('value', selectValue).text(item.text());
uiDropdown.removeClass('z-ui-dropdown-open');
$.isFunction(callback) && callback(item.text(), selectValue);
});
});
}
/**
* Dropdown单选下拉框指令的实现
* name : 区分不同的下拉框组件,字符串形式
* ngModel : 单选下拉框绑定的值,默认是选中项的key值
* dataList : 下拉框下拉选项列表,数组形式,数组元素对象包含key 以及value。key作为向后台交互的值,value作为前端控件显示的值
* empty : 布尔属性值,当赋值为true的时候,对下拉框组件进行充值,下拉框中的值显示的是placeholder的值"请选择"
* TODO : 多层级联下拉框的实现方法 ------ 当下拉框列表接受点击事件时,广播带有组件name值为参数的selectUpdate的事件,用户可以捕获事件,根据时间的参数做出相应的响应。
* 下拉框未选为空的状态
* 下拉框相应双向数据绑定的model,当model变化时,对应的下拉框组件可以显示对应的选项
*/
app.directive('dropdown',function(){
return {
restrict : 'EA',
replace: true,
template : '<div class="ui-form-item-group">'+
'<div class="ui-dropdown" ng-click="dropdown()">'+
'<div class="ui-dropdown-hd">'+
'<a href="javascript:;" role="button" title="请选择" class="ui-dropdown-current">请选择</a> <i class="vipFont i-arrow-up"></i> <i class="vipFont i-arrow-down"></i>'+
'</div>'+
'<div class="ui-dropdown-bd">'+
'<ul class="ui-dropdown-menu" >'+
'<li ng-repeat="item in datalist" >'+
'<a href="javascript:;" role="button" value="item.key" ng-click="select()">{{item.value}}</a>'+
'</li>'+
'</ul>'+
'</div>'+
'</div>'+
'</div>',
scope :{
name : '@',
ngModel : "=",
datalist : "=",
empty : "="
},
link : function(scope,iElement,iAttrs){
debugger
var $elem = $(iElement);
var dependents = scope.dependents ? scope.dependents.split(',') : false;
var parentScope = scope.$parent;
scope.name = scope.name || 'multi-select-' + Math.floor(Math.random() * 900000 + 100000);
scope.$watch('empty',function(newValue, oldValue, scope){
debugger
if(newValue != oldValue){
if( newValue == true){
$elem.find('.ui-dropdown').removeClass("z-ui-dropdown-selected");
$elem.find(".ui-dropdown-current").text('请选择');
}
}
})
scope.$watch('ngModel',function(newValue,oldValue,scope){
console.log('----------enter watch-------------');
debugger
if(newValue != oldValue){
scope.$root.$broadcast('selectUpdate', {
// 将变动的菜单的name属性广播出去,便于依赖于它的菜单进行识别
name: scope.name
});
for(var item in scope.datalist){
if(scope.datalist[item].key === newValue){
$elem.find(".ui-dropdown-current").text(scope.datalist[item].value);
}
}
}
})
scope.dropdown = function(){
$elem.find('.ui-dropdown').toggleClass("z-ui-dropdown-open");
}
scope.select = function(){
// "z-ui-dropdown-selected"
debugger
$elem.find(".ui-dropdown").addClass("z-ui-dropdown-selected");
scope.empty = false;
scope.ngModel = scope.datalist[this.$index].key;
// iAttrs["ngModel"] = "0"+this.$index;
// $elem.find(".ui-dropdown-current").text(scope.datalist[this.$index].value);
// scope.datafunc();
}
}
}
})
在页面中使用
<label class="ui-label label-margin">标记原因:</label>
<dropdown ng-model="formData.markReason" datalist="markReasons" name="markreasons-select"></dropdown>
级联事件的响应
$scope.$on('selectUpdate',function(e,data){
//TODO:
debugger
// console.log(data);
if(data.name == "risktypes-select"){
if($scope.formData.riskType == ''){
$scope.markReasons2 = [{key : '', value:"全部"}];
$scope.formData.markReason = '';
return ;
}
$scope.formData.markReason = '';
util.ajax({
"url": "XXXX",
"type": "post",
$http: $http,
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data: {
riskType: $scope.formData.riskType
},
success: function(res) {
if (!res) {
return _showMessage("对不起您没有权限", "信息错误");
}else if(res.success == false) {
return _showMessage("用户信息不匹配(未查到相关数据!)", "信息错误")
}else {
$scope.reasonListSeleted = res.results._defaultResult;
debugger
$scope.markReasons2 = [{key : '', value:"全部"}];
for (var i = 0; i < $scope.reasonListSeleted.length; i++) {
$scope.markReasons2.push({
key :
$scope.reasonListSeleted[i].reasonId,
value :
$scope.reasonListSeleted[i].reasonDesc
});
}
};
}
});
}
})
相关注意点
- 指令绑定参数时,最好不要是基本数据类型
指令在进行值绑定的时候,传入的值最好是非基本类型。譬如绑定一个字符串类型riskType
到ngModel
上,ngModel
需要双向数据绑定。
<dropdown ng-model="riskType" datalist="riskTypes">
这样的绑定会出现一定的问题
最好在controller中传入的参数的对象的属性,如下
<dropdown ng-model="obj.riskType" datalist="riskTypes">
在这个示例中datalist绑定的数据是数组类型,并非是简单数据类型,所以直接绑定即可。
扩展
后期又对下拉框进行优化,支持disable,搜索筛选选项等功能。
app.directive('searchdropdown',['$document','$filter','$timeout',function($document,$filter,$timeout){
return {
restrict : 'EA',
replace: true,
template : '<div class="ui-form-item-group">'+
'<div class="ui-dropdown" >'+
'<div class="ui-dropdown-hd">'+
'<input placeholder="请选择,输入可筛选" class="ui-dropdown-search" ng-model="searchData" style="border: none;font: inherit;" ng-show="searchable && searching">'+
'<a href="javascript:;" role="button" title="请选择" class="ui-dropdown-current" ng-show="!(searchable && searching) " ng-click="dropdown()">请选择</a> <i class="vipFont i-arrow-up" ng-click="dropdown()"></i> <i class="vipFont i-arrow-down" ng-click="dropdown()"></i>'+
'</div>'+
'<div class="ui-dropdown-bd | filter:searchData">'+
'<ul class="ui-dropdown-menu" >'+
'<li ng-repeat="item in datalist | filter:{text:searchData}" >'+
'<a href="javascript:;" role="button" value="item.value" ng-click="select($event)">{{item.text}}</a>'+
'</li>'+
'</ul>'+
'</div>'+
'</div>'+
'</div>',
scope :{
ngModel : "=",
datalist : "=",
disabled : "=",
searchable : "="
},
controller : function($scope){
$scope.name = $scope.name || 'dropdown-' + Math.floor(Math.random() * 900000 + 100000);
$scope.searching = false;
$scope.myComparator = function (expected, actual) {
return angular.equals(expected.toLowerCase(), actual.toLowerCase());
}
},
link : function(scope,iElement,iAttrs){
var $elem = $(iElement);
for(var item in scope.datalist){
if(scope.datalist[item].value === scope.ngModel){
$elem.find(".ui-dropdown-current").text(scope.datalist[item].text);
$elem.find(".ui-dropdown").addClass("z-ui-dropdown-selected");
}
}
if(scope.disabled == true){
$elem.find(".ui-dropdown").addClass("z-ui-dropdown-disable");
}
$elem.find('.ui-dropdown-search').bind('focus',function(event){
console.log('ui-dropdown-search is on focus');
$elem.find('.ui-dropdown').addClass("z-ui-dropdown-open");
event.stopPropagation();
})
// $elem.find(".ui-dropdown-hd").bind('blur',function(){
// alert('blur');
// })
// $elem.find('.ui-dropdown-search').bind('blur',function(event){
// console.log('ui-dropdown-search is on blur');
// scope.$apply(function(){
// scope.searching = false;
// })
// })
scope.dropdown = function(){
console.log("ui-dropdown trigger dropdown event");
if(scope.disabled)
return ;
$elem.find('.ui-dropdown').toggleClass("z-ui-dropdown-open");
if($elem.find('.ui-dropdown').hasClass("z-ui-dropdown-open")){
console.log("---------" + scope.name +"------bind $document event -----------");
// 对于这种问题,jQuery的解决方案是使用事件绑定的命名空间。即在事件名称后添加 .something 来区分自己这部分行为逻辑范围。
$(document).bind("click."+scope.name, function(event) {
console.log("-------go into $document click"+scope.name+"-------");
var judge = $(event.target).closest($elem).length > 0;
// if(!$elem.find('.ui-dropdown').hasClass("z-ui-dropdown-open")){
// console.log("---------" + scope.name +"------unbind $document event -----------");
// $(document).unbind("click."+scope.name);
// }
if(!judge){
if(scope.searchable && scope.searching) {
scope.$apply(function(){
scope.searching = false;
})
}
$elem.find(".ui-dropdown").removeClass("z-ui-dropdown-open");
$(document).unbind("click."+scope.name);
}
});
}else{
console.log("---------" + scope.name +"------unbind $document event -----------");
$(document).unbind("click."+scope.name);
}
if(scope.searchable){
scope.searching = !scope.searching;
// if(scope.searching){
scope.searchData = scope.ngModel;
var timer = $timeout(
function() {
$elem.find('.ui-dropdown-search').focus();
console.log( "Timeout executed", Date.now() );
},100);
scope.$on("$destroy",function( event ) {
$timeout.cancel( timer );
});
// }
}
}
scope.select = function($event){
$elem.find(".ui-dropdown").addClass("z-ui-dropdown-selected");
var temp = $filter('filter')(scope.datalist,scope.searchData);
console.log(temp);
scope.ngModel = temp[this.$index].value;
$elem.find(".ui-dropdown-current").text(temp[this.$index].text)
$elem.find(".ui-dropdown").removeClass("z-ui-dropdown-open");
scope.searching = false;
console.log(scope.searching);
}
scope.$watch('ngModel',function(newValue,oldValue,scope){
var isHitted = false;
if(newValue != oldValue){
for(var item in scope.datalist){
if(scope.datalist[item].value === newValue){
$elem.find(".ui-dropdown-current").text(scope.datalist[item].text);
$elem.find(".ui-dropdown").addClass("z-ui-dropdown-selected");
isHitted = true;
}
}
if(!isHitted){
$elem.find(".ui-dropdown-current").text('请选择');
$elem.find(".ui-dropdown").removeClass("z-ui-dropdown-selected");
}
}
})
// $(document).bind("click."+scope.name, function(event) {
// console.log("-------go into $document click-------");
// var judge = $(event.target).closest($elem).length > 0;
// if(!judge){
// if(scope.searchable && scope.searching) {
// scope.$apply(function(){
// scope.searching = false;
// })
// }
// $elem.find(".ui-dropdown").removeClass("z-ui-dropdown-open");
// }
// });
// $document.bind("click", function(event) {
// var judge = $(event.target).closest($elem).length > 0;
// if(!judge){
// if(scope.searchable && scope.searching) {
// // $elem.find('.ui-dropdown-search').blur();
// // console.log('manually trigger blur');
// scope.$apply(function(){
// scope.searching = false;
// })
// }
// $elem.find(".ui-dropdown").removeClass("z-ui-dropdown-open");
// }
// });
// $(document).one("click", function(event) {
// var judge = $(event.target).closest($elem).length > 0;
// if(!judge){
// if(scope.searchable && scope.searching) {
// // $elem.find('.ui-dropdown-search').blur();
// // console.log('manually trigger blur');
// scope.$apply(function(){
// scope.searching = false;
// })
// }
// $elem.find(".ui-dropdown").removeClass("z-ui-dropdown-open");
// }
// });
}
}
}])
simple-select.gif
search-select.gif
disbaled.png
AngularJS中实现无限级联动菜单
directive('multiLevelSelect', ['$parse', '$timeout', function ($parse, $timeout) {
// 利用闭包,保存父级scope中的所有多级联动菜单,便于取值
var selects = {};
return {
restrict: 'CA',
scope: {
// 用于依赖声明时指定父级标签
name: '@name',
// 依赖数组,逗号分割
dependents: '@dependents',
// 提供具体option值的函数,在父级change时被调用,允许同步/异步的返回结果
// 无论同步还是异步,数据应该是[{text: 'text', value: 'value'},]的结构
source: '=source',
// 是否支持控制选项,如果是,空值的标签是什么
empty: '@empty',
// 用于parse解析获取model值(而非viewValue值)
modelName: '@ngModel'
},
template: ''
// 使用ng-show而非ng-if,原因上文已经提到
+ '<option ng-show="empty" value="">{{empty}}</option>'
// 使用朴素的ng-repeat
+ '<option ng-repeat="item in items" value="{{item.value}}">{{item.text}}</option>',
require: 'ngModel',
link: function (scope, elem, attr, model) {
var dependents = scope.dependents ? scope.dependents.split(',') : false;
var parentScope = scope.$parent;
scope.name = scope.name || 'multi-select-' + Math.floor(Math.random() * 900000 + 100000);
// 将当前菜单的getValue函数封装起来,放在闭包中的selects对象中方便调用
selects[scope.name] = {
getValue: function () {
return $parse(scope.modelName)(parentScope);
}
};
// 保存初始值,原因上文已经提到
var initValue = selects[scope.name].getValue();
var inited = !initValue;
model.$setViewValue('');
// 父级标签变化时被调用的回调函数
function onParentChange() {
var values = {};
// 获取所有依赖的菜单的当前值
if (dependents) {
$.each(dependents, function (index, dependent) {
values[dependent] = selects[dependent].getValue();
});
}
// 利用闭包判断io造成的异步过期
(function (thenValues) {
// 调用source函数,取新的option数据
var returned = scope.source ? scope.source(values) : false;
// 利用多层闭包,将同步结果包装为有then方法的对象
!returned || (returned = returned.then ? returned : {
then: (function (data) {
return function (callback) {
callback.call(window, data);
};
})(returned)
}).then(function (items) {
// 防止由异步造成的过期
for (var name in thenValues) {
if (thenValues[name] !== selects[name].getValue()) {
return;
}
}
scope.items = items;
$timeout(function () {
// 防止由同步(严格的说也是异步,注意事件队列)造成的过期
if (scope.items !== items) return;
// 如果有空值,选择空值,否则选择第一个选项
if (scope.empty) {
model.$setViewValue('');
} else {
model.$setViewValue(scope.items[0].value);
}
// 判断恢复初始值的条件是否成熟
var initValueIncluded = !inited && (function () {
for (var i = 0; i < scope.items.length; i++) {
if (scope.items[i].value === initValue) {
return true;
}
}
return false;
})();
// 恢复初始值
if (initValueIncluded) {
inited = true;
model.$setViewValue(initValue);
}
model.$render();
});
});
})(values);
}
// 是否有依赖,如果没有,直接触发onParentChange以还原初始值
!dependents ? onParentChange() : scope.$on('selectUpdate', function (e, data) {
if ($.inArray(data.name, dependents) >= 0) {
onParentChange();
}
});
// 对当前值进行监听,发生变化时对其进行广播
parentScope.$watch(scope.modelName, function (newValue, oldValue) {
if (newValue || '' !== oldValue || '') {
scope.$root.$broadcast('selectUpdate', {
// 将变动的菜单的name属性广播出去,便于依赖于它的菜单进行识别
name: scope.name
});
}
});
}
};
}]);
angularJS中组件复用和封装
https://www.zybuluo.com/lxjwlt/note/331587
http://www.jb51.net/article/58229.htm
网友评论