当最初在范围内设置值时,日期选择器弹出格式不起作用
Datepicker-popup formatting not working when value set initially in scope
我正在使用 Angular UI bootstrap 日期选择器弹出窗口,在 Plunker (http://plnkr.co/edit/053VJYm1MpZUiKwFTfrT?p=preview) 上使用此自定义指令:
//Module
var userModule = angular.module("userModule",['ui.bootstrap']);
//Controller
userModule.controller("sampleController", ['$scope', function ($scope) {
$scope.minDate = new Date();
}]);
//Directive code
userModule.directive('datePicker', [function (dateFilter) {
return {
restrict: 'E',
require: 'ngModel',
scope: {
ngModel: '=',
ngReadonly: '=?',
minDate: '=?',
maxDate: '=?',
dtpRequired: '=?',
dateOptions: '=?'
},
template: '<p class="input-group">' +
'<input type="text" style="cursor:pointer" class="form-control" datepicker-popup="{{format}}"' +
'ng-model="ngModel" is-open="opened"' +
'min-date="minDate" max-date="maxDate"' +
'datepicker-options="dateOptions" date-disabled="disabled(date, mode)"' +
'ng-required="dtpRequired" close-text="Close" ng-readonly="ngReadonly" ng-click="openPopup()" />' +
'<span class="input-group-btn">' +
'<button type="button" class="btn btn-default" ng-click="openPopup($event)">' +
'<i class="fa fa-calendar"></i></button>' +
'</span>' +
'</p>',
controller: function ($scope) {
// check if it was defined. If not - set a default
$scope.dateOptions = $scope.dateOptions || {
formatYear: 'yy',
startingDay: 1,
showWeeks: false
};
$scope.openPopup = function ($event) {
if ($event !== undefined) {
$event.stopPropagation();
}
$scope.opened = true;
};
$scope.format = 'dd MMMM yyyy';
},
link: function ($scope, element, attrs, controller) {
//remove the default formatter from the input directive to prevent conflict
controller.$formatters.shift();
}
};
}]);
这工作正常,从日历弹出窗口中选择日期时日期格式正确。但是,如果我在控制器中设置 ng-model 的日期,则该日期不会被格式化为 'dd MMMM yyyy' 并作为日期字符串返回,例如 Sat Oct 01 2016 01:00:00 GMT+0100 (GMT Daylight时间)。但是在 Plunker 中,我可以在控制器中设置一个日期并且它的格式很好。
这是我的 HTML 日期选择器:
<date-picker ng-model="startDate.value" datepicker-options="dateOptions" min-date="minDate" ng-readonly="true"></date-picker>
在我的控制器中startDate.value = new Date();
我不确定问题出在哪里。下图显示了我要返回的内容。
我在本地尝试了您的代码,它似乎运行良好,没有任何问题。
我尝试了各种更改日期的方法,但一切正常。
plnkr 中的示例与您发布的示例之间似乎有些不同,特别是您引用日期的方式(您说您正在使用 startDate.value = new Date(); ,但在 plnkr 中我看到 ng-model="dtpValue1" 。这让我觉得你还缺少其他东西,我建议做一个完整的在本地可测试的 .zip 文件中的示例。此外,由于有可能没有人能够再次复制它,因此您拥有的所有 chrome 扩展名和操作系统的列表将很有用,最重要的是你应该尝试在其他机器上重现它并报告结果。
一般来说,我测试过的每台机器上预期工作的东西都按预期工作,我没有看到它不应该工作的充分理由。
如果我能够重现问题,我可以设置断点并弄清楚到底发生了什么,但目前这是不可能的,我们应该关注如何重现问题。
提供的信息似乎不足以解决这个问题。
这是因为 bootstrap UI 日期选择器实际上与字符串一起工作,而您正试图将 javascript 日期对象分配给 UI [=13] 的变量=] 适用于 angular 控制器。它们是不同类型的数据,因此会导致错误。如果您尝试控制变量的类型,在 select 之后弹出一个来自日期选择器的日期。你会看到它是一个字符串。所以.. 如果你想从你的控制器设置一个日期,你只需要将它设置为字符串,而不是 javascript 对象。
终于找到解决办法了。我从 Angular-UI-Bootstrap 更改为 uib-datepicker 指令,现在当在控制器中设置日期时它可以正确格式化日期!这是我的指令中的 HTML 模板以供参考:
template: '<p class="input-group">' +
'<input type="text" style="cursor:pointer" class="form-control" uib-datepicker-popup="{{format}}"' +
'ng-model="ngModel" is-open="opened"' +
'min-date="minDate" max-date="maxDate"' +
'datepicker-options="dateOptions"date-disabled="disabled(date, mode)"' +
'ng-required="dtpRequired" close-text="Close" ng-readonly="ngReadonly" ng-click="openPopup()" />' +
'<span class="input-group-btn">' +
'<button type="button" class="btn btn-default" ng-click="openPopup($event)">' +
'<i class="fa fa-calendar"></i></button>' +
'</span>' +
'</p>'
我写这个指令是为了将 string
表单服务器转换为 uib-datepicker-popup 需要的有效 javascript 格式:
app.directive('datepickerLocaleDate', ["$rootScope", "$filter", function ($rootScope, $filter) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
if (ngModel) {
// convert string to valid javascript fprmat
setTimeout(() => {
ngModel.$setViewValue(new Date(ngModel['$viewValue']));
}, 3000);
ngModel.$parsers.push(function (value) {
return new Date(value);
});
ngModel.$formatters.push(function (value) {
return value ? $filter('date')(value, 'yyyy/MM/dd') : null;
});
}
}
};
}]);
我正在使用 Angular UI bootstrap 日期选择器弹出窗口,在 Plunker (http://plnkr.co/edit/053VJYm1MpZUiKwFTfrT?p=preview) 上使用此自定义指令:
//Module
var userModule = angular.module("userModule",['ui.bootstrap']);
//Controller
userModule.controller("sampleController", ['$scope', function ($scope) {
$scope.minDate = new Date();
}]);
//Directive code
userModule.directive('datePicker', [function (dateFilter) {
return {
restrict: 'E',
require: 'ngModel',
scope: {
ngModel: '=',
ngReadonly: '=?',
minDate: '=?',
maxDate: '=?',
dtpRequired: '=?',
dateOptions: '=?'
},
template: '<p class="input-group">' +
'<input type="text" style="cursor:pointer" class="form-control" datepicker-popup="{{format}}"' +
'ng-model="ngModel" is-open="opened"' +
'min-date="minDate" max-date="maxDate"' +
'datepicker-options="dateOptions" date-disabled="disabled(date, mode)"' +
'ng-required="dtpRequired" close-text="Close" ng-readonly="ngReadonly" ng-click="openPopup()" />' +
'<span class="input-group-btn">' +
'<button type="button" class="btn btn-default" ng-click="openPopup($event)">' +
'<i class="fa fa-calendar"></i></button>' +
'</span>' +
'</p>',
controller: function ($scope) {
// check if it was defined. If not - set a default
$scope.dateOptions = $scope.dateOptions || {
formatYear: 'yy',
startingDay: 1,
showWeeks: false
};
$scope.openPopup = function ($event) {
if ($event !== undefined) {
$event.stopPropagation();
}
$scope.opened = true;
};
$scope.format = 'dd MMMM yyyy';
},
link: function ($scope, element, attrs, controller) {
//remove the default formatter from the input directive to prevent conflict
controller.$formatters.shift();
}
};
}]);
这工作正常,从日历弹出窗口中选择日期时日期格式正确。但是,如果我在控制器中设置 ng-model 的日期,则该日期不会被格式化为 'dd MMMM yyyy' 并作为日期字符串返回,例如 Sat Oct 01 2016 01:00:00 GMT+0100 (GMT Daylight时间)。但是在 Plunker 中,我可以在控制器中设置一个日期并且它的格式很好。 这是我的 HTML 日期选择器:
<date-picker ng-model="startDate.value" datepicker-options="dateOptions" min-date="minDate" ng-readonly="true"></date-picker>
在我的控制器中startDate.value = new Date();
我不确定问题出在哪里。下图显示了我要返回的内容。
我在本地尝试了您的代码,它似乎运行良好,没有任何问题。 我尝试了各种更改日期的方法,但一切正常。 plnkr 中的示例与您发布的示例之间似乎有些不同,特别是您引用日期的方式(您说您正在使用 startDate.value = new Date(); ,但在 plnkr 中我看到 ng-model="dtpValue1" 。这让我觉得你还缺少其他东西,我建议做一个完整的在本地可测试的 .zip 文件中的示例。此外,由于有可能没有人能够再次复制它,因此您拥有的所有 chrome 扩展名和操作系统的列表将很有用,最重要的是你应该尝试在其他机器上重现它并报告结果。
一般来说,我测试过的每台机器上预期工作的东西都按预期工作,我没有看到它不应该工作的充分理由。
如果我能够重现问题,我可以设置断点并弄清楚到底发生了什么,但目前这是不可能的,我们应该关注如何重现问题。
提供的信息似乎不足以解决这个问题。
这是因为 bootstrap UI 日期选择器实际上与字符串一起工作,而您正试图将 javascript 日期对象分配给 UI [=13] 的变量=] 适用于 angular 控制器。它们是不同类型的数据,因此会导致错误。如果您尝试控制变量的类型,在 select 之后弹出一个来自日期选择器的日期。你会看到它是一个字符串。所以.. 如果你想从你的控制器设置一个日期,你只需要将它设置为字符串,而不是 javascript 对象。
终于找到解决办法了。我从 Angular-UI-Bootstrap 更改为 uib-datepicker 指令,现在当在控制器中设置日期时它可以正确格式化日期!这是我的指令中的 HTML 模板以供参考:
template: '<p class="input-group">' +
'<input type="text" style="cursor:pointer" class="form-control" uib-datepicker-popup="{{format}}"' +
'ng-model="ngModel" is-open="opened"' +
'min-date="minDate" max-date="maxDate"' +
'datepicker-options="dateOptions"date-disabled="disabled(date, mode)"' +
'ng-required="dtpRequired" close-text="Close" ng-readonly="ngReadonly" ng-click="openPopup()" />' +
'<span class="input-group-btn">' +
'<button type="button" class="btn btn-default" ng-click="openPopup($event)">' +
'<i class="fa fa-calendar"></i></button>' +
'</span>' +
'</p>'
我写这个指令是为了将 string
表单服务器转换为 uib-datepicker-popup 需要的有效 javascript 格式:
app.directive('datepickerLocaleDate', ["$rootScope", "$filter", function ($rootScope, $filter) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
if (ngModel) {
// convert string to valid javascript fprmat
setTimeout(() => {
ngModel.$setViewValue(new Date(ngModel['$viewValue']));
}, 3000);
ngModel.$parsers.push(function (value) {
return new Date(value);
});
ngModel.$formatters.push(function (value) {
return value ? $filter('date')(value, 'yyyy/MM/dd') : null;
});
}
}
};
}]);