angular-bootstrap ui-date组件问题总结
使用angular框架的时候,之前用的时间控件是引入My97DatePicker组件实现的,但是因为
1.My97DatePicker样式不太好看以及偶尔会出现底部被遮盖的情况、点击不可编辑input框使用backspace按钮会出现格式不符合问题
2.angular-bootstrap 自带兼容第三方ui-date,并且是基于bootstrap改造的
所以决定调研ui-date是否符合产品需求:
条件1.开始时间和结束时间之间有某种关系:开始时间可范围最大值不超过结束时间值,结束时间可选最小值不小于开始时间值
条件2.有选择今天日期按钮
条件3.不能有清除日期按钮
条件4.必须汉化
在引入该文件的时候,angular版本是1.5.0,angular-ui-bootstrap版本是1.1.2,修改代码后为
1 <p class="input-group"> 2 <input type="text" class="form-control" uib-datepicker-popup readonly ng-model="dicQueryObj.startTime" is-open="startPopupOpened" min-date="minStartDate" max-date="maxStartDate" datepicker-options="dateOptions" ng-required="true" close-text="关闭" current-text="今天"/> 3 <span class="input-group-btn"> 4 <button type="button" class="btn btn-default" ng-click="startOpen()"><i class="glyphicon glyphicon-calendar"></i></button> 5 </span> 6</p>
1 <p class="input-group"> 2 <input type="text" class="form-control" uib-datepicker-popup readonly ng-model="dicQueryObj.endTime" is-open="endPopupOpened" min-date="minEndDate" max-date="maxEndDate" datepicker-options="dateOptions" ng-required="true" close-text="关闭" current-text="今天" /> 3 <span class="input-group-btn"> 4 <button type="button" class="btn btn-default" ng-click="endOpen()"><i class="glyphicon glyphicon-calendar"></i></button> 5 </span> 6</p>
//初始化查询条件
$scope.dicQueryObj = {
fileName: '',
startTime:new Date(CommonServ.getLastMonthDate()),
endTime: new Date(CommonServ.getCurDate()),
order: '0'
};
//时间选择器配置
$scope.minStartDate = 0; //开始时间的最小时间
$scope.maxStartDate = $scope.dicQueryObj.endTime; //开始时间的最大可选时间
$scope.minEndDate = $scope.dicQueryObj.startTime; //结束时间的最小可选时间要大于开始时间的设定值
$scope.maxEndDate = $scope.dicQueryObj.endTime; //结束时间的最大可选择时间不超过结束时间的设定值
$scope.$watch('dicQueryObj.startTime', function(v){
$scope.minEndDate = v;
});
$scope.$watch('dicQueryObj.endTime', function(v){
$scope.maxStartDate = v;
});
$scope.dateOptions = {
formatYear: 'yy',
maxDate: new Date(),
startingDay: 1
};
$scope.startOpen = function() {
$timeout(function() {
$scope.startPopupOpened = true;
});
};
$scope.endOpen = function() {
$timeout(function() {
$scope.endPopupOpened = true;
});
};
$scope.startPopupOpened = false;
$scope.endPopupOpened = false;
然后隐藏清除按钮:
1 /*ui-date样式*/ 2 .uib-button-bar .btn-group button[ng-click^="select(null)"] { 3 display: none; 4 }
效果界面显示如下:
条件1、条件2、条件3都符合,然后被组内小伙伴测出来bug!!!
bug描述:因为设置了日期可选范围,界面确实对范围外的日期呈不可选状态,不可点击,然后顶部前后年份以及月份都可滑动,关键是每次切换月份,月份的1号都会被莫名的自动选中,导致我ng-model绑定的数据变化!!然而居然$watch不出来!!!我就纳闷了?
然后尝试看源码,然而各种看不懂啊。只有类似一句self.activeDate(year,mouth,1),然而各种注释都木有用,各种按照issue上面改代码,然而作者说版本更新已经不适用了。。。我就放弃了,再说改源码毕竟不好啊!
中途各种看issues(https://github.com/angular-ui/bootstrap/issues?utf8=%E2%9C%93)发现人家标为这是bug!!!
http://angular-ui.github.io/bootstrap/#/datepicker无奈研究了一下官网,他并没有出现我遇到的问题,查看他用的版本,发现人用的版本不一样啊!!!
然后重新下载版本bower install angular-bootstrap#1.3.2,引入解决了bug!
到目前为止就剩下条件4汉化了,查了一下issue,结果...
就在快要放弃的时候,大牛说是引入中文文件就OK,毕竟它改造之前是可以支持中文版本的,然后开始各种找,找到了i18n,bower install angular-i18n,下下来发现各种文件
然而查看发现
require('./angular-locale_zh-cn');
module.exports = 'ngLocale';
。。好吧 这个angular2.0的代码
但是ngLocale这个模块貌似就是汉化的重要线索,然后就找到这个了http://stackoverflow.com/questions/19671887/angularjs-angular-ui-bootstrap-changing-language-used-by-the-datepicker
里面提到解决方法,扒下来汉化文件https://github.com/angular/angular.js/blob/master/src/ngLocale/angular-locale_zh.js
然后引进项目中,完全汉化了!效果如下:
注意1:min-date以及max-date设置从html中转义至controller中的options设置
<p class="input-group"> <input type="text" class="form-control" uib-datepicker-popup readonly ng-model="newWordQueryObj.startTime" is-open="startPopupOpened" datepicker-options="startDateOptions" ng-required="true" close-text="关闭" current-text="今天" /> <span class="input-group-btn"> <button type="button" class="btn btn-default" ng-click="startOpen()"><i class="glyphicon glyphicon-calendar"></i></button> </span> </p> <p class="input-group"> <input type="text" class="form-control" uib-datepicker-popup readonly ng-model="newWordQueryObj.endTime" is-open="endPopupOpened" datepicker-options="endDateOptions" ng-required="true" close-text="关闭" current-text="今天" /> <span class="input-group-btn"> <button type="button" class="btn btn-default" ng-click="endOpen()"><i class="glyphicon glyphicon-calendar"></i></button> </span> </p>
JS代码修改:
1 //初始化查询条件 2 $scope.newWordQueryObj = { 3 fileName: '', 4 startTime: new Date(CommonServ.getLastMonthDate()), 5 endTime: new Date(CommonServ.getCurDate()), 6 order: '0' 7 }; 8 9 10 //时间选择器配置 11 //$scope.minStartDate = 0; //开始时间的最小时间 12 //$scope.maxStartDate = $scope.newWordQueryObj.endTime; //开始时间的最大可选时间 13 //$scope.minEndDate = $scope.newWordQueryObj.startTime; //结束时间的最小可选时间要大于开始时间的设定值 14 //$scope.maxEndDate = $scope.newWordQueryObj.endTime; //结束时间的最大可选择时间不超过结束时间的设定值 15 $scope.startDateOptions = { 16 formatYear: 'yy', 17 maxDate: $scope.newWordQueryObj.endTime, 18 startingDay: 1 19 }; 20 $scope.endDateOptions = { 21 formatYear: 'yy', 22 minDate: $scope.newWordQueryObj.startTime, 23 maxDate: new Date(), 24 startingDay: 1 25 }; 26 27 $scope.$watch('newWordQueryObj.startTime', function(newValue,oldValue){ 28 //$scope.minEndDate = newValue; 29 $scope.endDateOptions.minDate = newValue; 30 }); 31 $scope.$watch('newWordQueryObj.endTime', function(newValue,oldValue){ 32 //$scope.maxStartDate = newValue; 33 $scope.startDateOptions.maxDate = newValue; 34 }); 35 $scope.startOpen = function() { 36 $timeout(function() { 37 $scope.startPopupOpened = true; 38 }); 39 }; 40 $scope.endOpen = function() { 41 $timeout(function() { 42 $scope.endPopupOpened = true; 43 }); 44 }; 45 $scope.startPopupOpened = false; 46 $scope.endPopupOpened = false; 47
注意2:这时如果要隐藏clear清除按钮,css代码得改变
1 /*ui-date样式*/ 2 .uib-button-bar .btn-group button[ng-click^="select(null, $event)"] { 3 display: none; 4 }
完成~
接下来就可以重新测试一下了~
备注:
此时对accordion来说,如果自定义了templateUrl,此时templateUrl内需要添加一个属性uib-accordion-header
1 <span data-toggle="collapse" aria-expanded="{{isOpen}}" aria-controls="{{::panelId}}" tabindex="0" class="accordion-toggle" uib-accordion-transclude="heading"><span ng-class="{'text-muted': isDisabled}" uib-accordion-header>{{heading}}</span></span>