使用 AngularJS 和 UI Bootstrap 的多个日期选择器的奇怪行为
Odd behaviour with multiple datepickers using AngularJS and UI Bootstrap
我正在使用 AngularJS 和 UI Bootstrap 编写一个应用程序,我正在尝试实现一个模式,用户可以在其中选择开始日期和结束日期对于一个事件。我遇到的问题是,当用户选择结束日期时,开始日期也会受到影响,从而导致值不正确。
我在这里做了一个最小的测试用例:http://147.75.205.135/test/
(我尝试使用 Plunkr 重现它,但出于某种原因我在那里没有得到相同的行为)
笨蛋link:http://plnkr.co/edit/kika1viHi8csXMuklw8Z
要重现问题,请单击 "Launch" 按钮,打开开始日期的日期选择器,然后单击向右箭头转到下个月并选择一个日期。然后对于结束日期,单击向右箭头转到下个月并选择任何日期。然后点击"Save"。将出现一个警告框,显示开始和结束日期,但开始日期与日期选择器中选择的日期不对应,它设置为结束日期选择的月份的 1 号。
我在 http://147.75.205.135/test/script/angular/main.js 中将其确定为以下函数:
$scope.adjustEndDate = function() {
if ($scope.endDate < $scope.startDate) {
console.log("Adjusting end date to " + $scope.startDate);
$scope.endDate = $scope.startDate;
}
};
它是从 ng-change
开始日期选择器上调用的。将其注释掉会使奇怪的行为消失。但是我不明白为什么会导致这个问题。我需要这个功能,以便当用户选择开始日期时,结束日期会自动调整,使其永远不会早于开始日期。
完整代码:
index.html
<!doctype html>
<html>
<head>
<title>Test page</title>
<link rel="stylesheet" href="bootswatch-dist/css/bootstrap.min.css"></link>
<link rel="stylesheet" href="css/main.css"></link>
<script>
var conf = {
templates: {
datepickModal: "script/angular/templates/datepickModal.html"
}
};
</script>
<script src="angular/angular.js" ></script>
<script src="jquery/dist/jquery.min.js"></script>
<script src="angular-animate/angular-animate.js"></script>
<script src="angular-bootstrap/ui-bootstrap.js"></script>
<script src="angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="script/angular/main.js"></script>
</head>
<body data-ng-app="mainApp">
<div id="main" ng-controller="testCtrl">
<button ng-click="openModal()">Launch modal</button>
</div>
</body>
</html>
main.js
+function(angular, d3) {
"use strict";
var app = angular.module('mainApp', ['ui.bootstrap']);
app.controller('datepickCtrl', ['$scope', '$rootScope', '$uibModalInstance', function($scope, $rootScope, $uibModalInstance) {
$scope.startDate = new Date();
$scope.endDate = new Date();
$scope.startOpened = false;
$scope.endOpened = false;
$scope.name = '';
$scope.mode = 'list';
$scope.save = function () {
alert("Saving dates start: " + $scope.startDate + " and end " + $scope.endDate);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
$scope.toggleStartCalendar = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.startOpened = !$scope.startOpened;
};
$scope.toggleEndCalendar = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.endOpened = !$scope.endOpened;
};
$scope.dateOptions = {
formatYear: 'yy',
startingDay: 1
};
$scope.setMode = function(mode) {
$scope.mode = mode;
}
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
$scope.adjustEndDate = function() {
if ($scope.endDate < $scope.startDate) {
console.log("Adjusting end date to " + $scope.startDate);
$scope.endDate = $scope.startDate;
}
};
$scope.adjustStartDate = function() {
if ($scope.startDate > $scope.endDate) {
console.log("Adjusting start date to " + $scope.endDate);
$scope.startDate = $scope.endDate;
}
};
}]);
app.controller('testCtrl', ['$scope', '$rootScope', '$uibModal', function($scope, $rootScope, $uibModal) {
$scope.openModal = function() {
if (conf.suspended) {
return;
}
var modalInstance = $uibModal.open({
animation: true,
templateUrl: conf.templates.datepickModal,
controller: 'datepickCtrl',
size: 'md'
});
};
}]);
}(window.angular, window.d3);
modal.html
<div class="modal-header">
<h3 class="modal-title">Datepick tester</h3>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-6">
<p class="input-group">
<label for="startdate">Start date</label><p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup ng-model="startDate" ng-change="adjustEndDate()" is-open="startOpened" ng-required="true" uib-datepicker-options="dateOptions" name="startdate" ng-click="toggleStartCalendar($event)"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="toggleStartCalendar($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
<div class="col-md-6">
<p class="input-group">
<label for="enddate">End date</label><p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup ng-model="endDate" is-open="endOpened" ng-change="adjustStartDate()" ng-required="true" uib-datepicker-options="dateOptions" name="enddate" ng-click="toggleEndCalendar($event)"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="toggleEndCalendar($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="save()">Save</button>
<button class="btn btn-warning" ng-click="cancel()">Close</button>
</div>
使用的版本
- AngularJS: 1.4.8
- JQuery: 2.1.4
- UI-bootstrap: 1.2.4
我遇到了同样的问题。问题是您要在此处复制 Date 对象:
$scope.endDate = $scope.startDate
只需将其更改为:
$scope.endDate = 新日期($scope.startDate.getTime())
我正在使用 AngularJS 和 UI Bootstrap 编写一个应用程序,我正在尝试实现一个模式,用户可以在其中选择开始日期和结束日期对于一个事件。我遇到的问题是,当用户选择结束日期时,开始日期也会受到影响,从而导致值不正确。
我在这里做了一个最小的测试用例:http://147.75.205.135/test/
(我尝试使用 Plunkr 重现它,但出于某种原因我在那里没有得到相同的行为)
笨蛋link:http://plnkr.co/edit/kika1viHi8csXMuklw8Z
要重现问题,请单击 "Launch" 按钮,打开开始日期的日期选择器,然后单击向右箭头转到下个月并选择一个日期。然后对于结束日期,单击向右箭头转到下个月并选择任何日期。然后点击"Save"。将出现一个警告框,显示开始和结束日期,但开始日期与日期选择器中选择的日期不对应,它设置为结束日期选择的月份的 1 号。
我在 http://147.75.205.135/test/script/angular/main.js 中将其确定为以下函数:
$scope.adjustEndDate = function() {
if ($scope.endDate < $scope.startDate) {
console.log("Adjusting end date to " + $scope.startDate);
$scope.endDate = $scope.startDate;
}
};
它是从 ng-change
开始日期选择器上调用的。将其注释掉会使奇怪的行为消失。但是我不明白为什么会导致这个问题。我需要这个功能,以便当用户选择开始日期时,结束日期会自动调整,使其永远不会早于开始日期。
完整代码:
index.html
<!doctype html>
<html>
<head>
<title>Test page</title>
<link rel="stylesheet" href="bootswatch-dist/css/bootstrap.min.css"></link>
<link rel="stylesheet" href="css/main.css"></link>
<script>
var conf = {
templates: {
datepickModal: "script/angular/templates/datepickModal.html"
}
};
</script>
<script src="angular/angular.js" ></script>
<script src="jquery/dist/jquery.min.js"></script>
<script src="angular-animate/angular-animate.js"></script>
<script src="angular-bootstrap/ui-bootstrap.js"></script>
<script src="angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="script/angular/main.js"></script>
</head>
<body data-ng-app="mainApp">
<div id="main" ng-controller="testCtrl">
<button ng-click="openModal()">Launch modal</button>
</div>
</body>
</html>
main.js
+function(angular, d3) {
"use strict";
var app = angular.module('mainApp', ['ui.bootstrap']);
app.controller('datepickCtrl', ['$scope', '$rootScope', '$uibModalInstance', function($scope, $rootScope, $uibModalInstance) {
$scope.startDate = new Date();
$scope.endDate = new Date();
$scope.startOpened = false;
$scope.endOpened = false;
$scope.name = '';
$scope.mode = 'list';
$scope.save = function () {
alert("Saving dates start: " + $scope.startDate + " and end " + $scope.endDate);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
$scope.toggleStartCalendar = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.startOpened = !$scope.startOpened;
};
$scope.toggleEndCalendar = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.endOpened = !$scope.endOpened;
};
$scope.dateOptions = {
formatYear: 'yy',
startingDay: 1
};
$scope.setMode = function(mode) {
$scope.mode = mode;
}
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
$scope.adjustEndDate = function() {
if ($scope.endDate < $scope.startDate) {
console.log("Adjusting end date to " + $scope.startDate);
$scope.endDate = $scope.startDate;
}
};
$scope.adjustStartDate = function() {
if ($scope.startDate > $scope.endDate) {
console.log("Adjusting start date to " + $scope.endDate);
$scope.startDate = $scope.endDate;
}
};
}]);
app.controller('testCtrl', ['$scope', '$rootScope', '$uibModal', function($scope, $rootScope, $uibModal) {
$scope.openModal = function() {
if (conf.suspended) {
return;
}
var modalInstance = $uibModal.open({
animation: true,
templateUrl: conf.templates.datepickModal,
controller: 'datepickCtrl',
size: 'md'
});
};
}]);
}(window.angular, window.d3);
modal.html
<div class="modal-header">
<h3 class="modal-title">Datepick tester</h3>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-6">
<p class="input-group">
<label for="startdate">Start date</label><p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup ng-model="startDate" ng-change="adjustEndDate()" is-open="startOpened" ng-required="true" uib-datepicker-options="dateOptions" name="startdate" ng-click="toggleStartCalendar($event)"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="toggleStartCalendar($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
<div class="col-md-6">
<p class="input-group">
<label for="enddate">End date</label><p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup ng-model="endDate" is-open="endOpened" ng-change="adjustStartDate()" ng-required="true" uib-datepicker-options="dateOptions" name="enddate" ng-click="toggleEndCalendar($event)"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="toggleEndCalendar($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="save()">Save</button>
<button class="btn btn-warning" ng-click="cancel()">Close</button>
</div>
使用的版本
- AngularJS: 1.4.8
- JQuery: 2.1.4
- UI-bootstrap: 1.2.4
我遇到了同样的问题。问题是您要在此处复制 Date 对象: $scope.endDate = $scope.startDate
只需将其更改为: $scope.endDate = 新日期($scope.startDate.getTime())