在 Angular UI bootstrap 日期选择器中检测所选月份
Detect the selected month in Angular UI bootstrap datepicker
我在我的项目中使用日模式的 Angular UI Bootstrap 日期选择器。如何在选择新日期之前获取当前开放月份?
您应该使用 ng-model 将选定的值分配给变量。如果使用原始作用域变量,则可以随时访问 Date 对象。例如:
<input ng-model="selectedDate" other-datepicker-directives />
然后在您的控制器中,selectedDate 值是一个 Date 对象,您可以访问该对象的正常日期属性;像 .getMonth()。如果您随后使用手表,则可以始终使用当前选择的月份设置局部变量!
因此,在您的控制器中:
$scope.$watch(function() { return $scope.selectedDate }, function()
{
// bail out if no selected date
if (!angular.isDefined($scope.selectedDate)) return;
$scope.selectedMonth = $scope.selectedDate.getMonth();
});
现在只要 $scope.selectedDate 发生变化,$scope.selectedMonth 就会更新。这意味着您可以在 HTML 视图中显示所选月份,如下所示:
所选月份:{{selectedMonth}}
希望对您有所帮助!
在花了一些时间试图找到正确的方式来获得这个之后,在阅读了 datepicker 指令和控制器的源代码之后,我找不到一种非肮脏的方式来获得当前月份,所以这里有一个非常hacky 方式来做到这一点。
警告,Angular-UI Bootstrap 的未来版本可能会破坏此方法
为此您需要使用 AngularJS decorators。这是您需要的代码:
angular.module('myApp', [
'ui.bootstrap'
])
.config(function($provide) {
$provide.decorator('datepickerDirective', function($delegate) {
var directive = $delegate[0];
//get a copy of the directive's original compile function
var directiveCompile = directive.compile;
//overwrite the original compile function
directive.compile = function(tElement, tAttrs) {
// call the directive's compile with apply to send the original 'this' and arguments to it
var link = directiveCompile.apply(this, arguments);
//here's where the magic starts
return function(scope, element, attrs, ctrls) {
//call the original link
link.apply(this, arguments);
//move is the internal function called when you click
//on the chevrons for previous and next month
var originalMove = scope.move;
scope.move = function(direction) {
originalMove.apply(this, arguments);
//when move is called, the 'this' object contains a 'title' property with the current month!
var currentMonth = this.title;
//emit the event to parent scopes
scope.$emit('datepicker.monthChanged', currentMonth);
}
}
};
return $delegate;
});
})
然后您的控制器可以收听 datepicker.monthChanged
:
$scope.$on('datepicker.monthChanged', function(event, newVal) {
$scope.currentMonth = newVal;
})
由于日期选择器控制器没有将当前选定的日期保存在 $scope
内,它将它保存在一个闭包变量中,我发现你可以获得选定月份的唯一方法是在 this
对象,当函数 move
被调用时。 move
在您单击上个月和下个月图标时调用。
这里有一个 plunkr 演示了这个装饰器的用法:http://plnkr.co/edit/iWJWjM8nCsh5TMupNioo?p=preview
/**
* 从一维数组中选出出现次数最多的项
* @param {Array} arr - 一维数组
* @see
*/
function getMaxOccurrence(arr) {
var arrMap = {},
maxCount = 0,
maxEl,
item;
var index = 0,
length = arr.length;
for (; index < length; index++) {
if (arr.hasOwnProperty(index)) {
item = arr[index];
arrMap.hasOwnProperty(item) ? ++arrMap[item] : (arrMap[item] = 1);
if (arrMap[item] > maxCount) {
maxCount = arrMap[item];
maxEl = item;
}
}
}
return maxEl;
}
$scope.datetimeOption = {
customClass: getDayClass,
showWeeks: false,
}
var tempYear = null;
var prevStartOfMonth = null;
var tempMonthMap = [];
function getDayClass(data) {
var date = data.date;
var mode = data.mode;
var selectedMonth = null;
var selectedDate = null;
var startOfMonth = null;
var endOfMonth = null;
if (tempMonthMap.length === 42) {
tempMonthMap = [];
}
if (mode === 'day') {
if (date.getMonth) {
tempMonthMap.push(moment(date).month());
}
if (tempMonthMap.length === 42) {
tempYear = moment(date).year();
selectedMonth = getMaxOccurrence(tempMonthMap);
selectedDate = moment({ year: tempYear, month: selectedMonth });
startOfMonth = moment(selectedDate).startOf('month').format('YYYY-MM-DD HH:mm:ss');
endOfMonth = moment(selectedDate).endOf('month').format('YYYY-MM-DD HH:mm:ss');
if (prevStartOfMonth !== startOfMonth) {
getListRequest({ since: startOfMonth, until: endOfMonth });
prevStartOfMonth = startOfMonth;
}
}
//
}
return '';
}
我在我的项目中使用日模式的 Angular UI Bootstrap 日期选择器。如何在选择新日期之前获取当前开放月份?
您应该使用 ng-model 将选定的值分配给变量。如果使用原始作用域变量,则可以随时访问 Date 对象。例如:
<input ng-model="selectedDate" other-datepicker-directives />
然后在您的控制器中,selectedDate 值是一个 Date 对象,您可以访问该对象的正常日期属性;像 .getMonth()。如果您随后使用手表,则可以始终使用当前选择的月份设置局部变量!
因此,在您的控制器中:
$scope.$watch(function() { return $scope.selectedDate }, function()
{
// bail out if no selected date
if (!angular.isDefined($scope.selectedDate)) return;
$scope.selectedMonth = $scope.selectedDate.getMonth();
});
现在只要 $scope.selectedDate 发生变化,$scope.selectedMonth 就会更新。这意味着您可以在 HTML 视图中显示所选月份,如下所示:
所选月份:{{selectedMonth}}
希望对您有所帮助!
在花了一些时间试图找到正确的方式来获得这个之后,在阅读了 datepicker 指令和控制器的源代码之后,我找不到一种非肮脏的方式来获得当前月份,所以这里有一个非常hacky 方式来做到这一点。
警告,Angular-UI Bootstrap 的未来版本可能会破坏此方法
为此您需要使用 AngularJS decorators。这是您需要的代码:
angular.module('myApp', [
'ui.bootstrap'
])
.config(function($provide) {
$provide.decorator('datepickerDirective', function($delegate) {
var directive = $delegate[0];
//get a copy of the directive's original compile function
var directiveCompile = directive.compile;
//overwrite the original compile function
directive.compile = function(tElement, tAttrs) {
// call the directive's compile with apply to send the original 'this' and arguments to it
var link = directiveCompile.apply(this, arguments);
//here's where the magic starts
return function(scope, element, attrs, ctrls) {
//call the original link
link.apply(this, arguments);
//move is the internal function called when you click
//on the chevrons for previous and next month
var originalMove = scope.move;
scope.move = function(direction) {
originalMove.apply(this, arguments);
//when move is called, the 'this' object contains a 'title' property with the current month!
var currentMonth = this.title;
//emit the event to parent scopes
scope.$emit('datepicker.monthChanged', currentMonth);
}
}
};
return $delegate;
});
})
然后您的控制器可以收听 datepicker.monthChanged
:
$scope.$on('datepicker.monthChanged', function(event, newVal) {
$scope.currentMonth = newVal;
})
由于日期选择器控制器没有将当前选定的日期保存在 $scope
内,它将它保存在一个闭包变量中,我发现你可以获得选定月份的唯一方法是在 this
对象,当函数 move
被调用时。 move
在您单击上个月和下个月图标时调用。
这里有一个 plunkr 演示了这个装饰器的用法:http://plnkr.co/edit/iWJWjM8nCsh5TMupNioo?p=preview
/**
* 从一维数组中选出出现次数最多的项
* @param {Array} arr - 一维数组
* @see
*/
function getMaxOccurrence(arr) {
var arrMap = {},
maxCount = 0,
maxEl,
item;
var index = 0,
length = arr.length;
for (; index < length; index++) {
if (arr.hasOwnProperty(index)) {
item = arr[index];
arrMap.hasOwnProperty(item) ? ++arrMap[item] : (arrMap[item] = 1);
if (arrMap[item] > maxCount) {
maxCount = arrMap[item];
maxEl = item;
}
}
}
return maxEl;
}
$scope.datetimeOption = {
customClass: getDayClass,
showWeeks: false,
}
var tempYear = null;
var prevStartOfMonth = null;
var tempMonthMap = [];
function getDayClass(data) {
var date = data.date;
var mode = data.mode;
var selectedMonth = null;
var selectedDate = null;
var startOfMonth = null;
var endOfMonth = null;
if (tempMonthMap.length === 42) {
tempMonthMap = [];
}
if (mode === 'day') {
if (date.getMonth) {
tempMonthMap.push(moment(date).month());
}
if (tempMonthMap.length === 42) {
tempYear = moment(date).year();
selectedMonth = getMaxOccurrence(tempMonthMap);
selectedDate = moment({ year: tempYear, month: selectedMonth });
startOfMonth = moment(selectedDate).startOf('month').format('YYYY-MM-DD HH:mm:ss');
endOfMonth = moment(selectedDate).endOf('month').format('YYYY-MM-DD HH:mm:ss');
if (prevStartOfMonth !== startOfMonth) {
getListRequest({ since: startOfMonth, until: endOfMonth });
prevStartOfMonth = startOfMonth;
}
}
//
}
return '';
}