Angular Материал md-datepicker выдает ошибку при нажатии

Я новичок здесь и испытываю некоторые проблемы с недавно доступным md-datepicker на Angular Материал 0.11.0: https://material.angularjs.org/0.11.0/#/demo/material.components.datepicker

Вкратце, мое приложение позволяет пользователям добавлять отдельные проекты с именем и описанием. Они также могут обновлять соответствующие детали проекта.

Оба добавления и обновления выполняются через Material Designs mdDialog. Когда пользователь нажимает на добавление или обновление, контроллер вызывает соответствующую функцию, которая вызывает соответствующую функцию в моем factory.

Функции factory содержат службу $mdDialog, которую я настроил. Я смог обновить и добавить без проблем, пока не добавлю md-datepicker.

У меня появилась следующая ошибка, когда я щелкнул, чтобы изменить.

TypeError: date.toLocaleDateString is not a function
at Object.defaultFormatDate [as formatDate] (angular-material.js:6858)
at DatePickerCtrl.configureNgModel.ngModelCtrl.$render (angular-material.js:7182)
at Object.ngModelWatch (angular.js:25353)
at Scope.parent.$get.Scope.$digest (angular.js:15751)
at Scope.parent.$get.Scope.$apply (angular.js:16030)
at done (angular.js:10545)
at completeRequest (angular.js:10717)
at XMLHttpRequest.requestLoaded (angular.js:10658)

Посмотрев вокруг, я понял, что должен настроить md-datepicker. Я принял вдохновение https://material.angularjs.org/HEAD/#/api/material.components.datepicker/service/ $mdDateLocaleProvider и добавил следующий код как .config к моему основному приложению AngularJS (я использую momentjs, чтобы дать пользователям дату основанные на их локали).

app.config(function($mdDateLocaleProvider) {
$mdDateLocaleProvider.formatDate = function(date) {
 return moment(date).format('L');
};});

Теперь я могу добавить проект со следующим кодом в мой 'add' factory. Я даже могу добавить дату по своему выбору, и я могу сохранить ее в firebase в эпоху.

return $mdDialog.show({
 clickOutsideToClose: true,
 controller: function($mdDialog) {
 var vm = this;
 vm.project = project;
 vm.add = function(project) {
 var date = new Date();
 project.deadline = date.getTime();
 if(project.deadline == undefined) {
 project.deadline = null;
 };
 FBprojects.$add(project);
 console.log(project);
 $mdDialog.hide();
 };
 },
 controllerAs: 'PAmodal',
 templateUrl: 'views/newproject.html',
 targetEvent: e
 })

Проблема возникает, когда я специально нажимаю на значок календаря md-datepicker, чтобы изменить дату (после того, как будет открыто обновление $mdDialog).

TypeError: date.getFullYear is not a function
at CalendarCtrl.getDateId (angular-material.js:6427)
at angular-material.js:6349
at processQueue (angular.js:14678)
at angular.js:14694
at Scope.parent.$get.Scope.$eval (angular.js:15922)
at Scope.parent.$get.Scope.$digest (angular.js:15733)
at Scope.parent.$get.Scope.$apply (angular.js:16030)
at HTMLButtonElement.<anonymous> (angular.js:23486)
at HTMLButtonElement.jQuery.event.dispatch (jquery.js:4435)
at HTMLButtonElement.jQuery.event.add.elemData.handle (jquery.js:4121)(anonymous function) @ angular.js:12450ident.$get @ angular.js:9237processQueue @ angular.js:14686(anonymous function) @ angular.js:14694parent.$get.Scope.$eval @ angular.js:15922parent.$get.Scope.$digest @ angular.js:15733parent.$get.Scope.$apply @ angular.js:16030(anonymous function) @ angular.js:23486jQuery.event.dispatch @ jquery.js:4435jQuery.event.add.elemData.handle @ jquery.js:4121
Uncaught TypeError: end.getFullYear is not a function
TypeError: date.getFullYear is not a function
at CalendarCtrl.getDateId (http://localhost:9000/bower_components/angular-material/angular-material.js:6427:12)
at CalendarCtrl.focus (http://localhost:9000/bower_components/angular-material/angular-material.js:6298:23)
at http://localhost:9000/bower_components/angular-material/angular-material.js:7372:30
at http://localhost:9000/bower_components/angular-material/angular-material.js:1068:11
at Array.forEach (native)
at processQueue (http://localhost:9000/bower_components/angular-material/angular-material.js:1067:15)
at http://localhost:9000/bower_components/angular/angular.js:17788:31
at completeOutstandingRequest (http://localhost:9000/bower_components/angular/angular.js:5498:10)
at http://localhost:9000/bower_components/angular/angular.js:5775:7
</anonymous>

В этот момент md-datepicker не знает, в каком году он находится, и начинается примерно в 1933 году. Как ни странно, если я не нажимаю на значок и сначала не меняю дату ввода, я могу щелкнуть значок, который приносит из календаря в правильную дату. Я могу это сделать, пока мой текущий mdDialog не закрыт. Затем, когда я нажимаю update, он иногда обновляет дату на firebase. Я до сих пор не понял, почему это непротиворечиво. Следующий код вызывается через контроллер для обновления проекта

. Если я оставлю md-datepicker нетронутым, я могу изменить другие данные.

updateProject: function(e, currentProject) {
 return $mdDialog.show({
 clickOutsideToClose: true,
 controller: function($mdDialog) {
 var vm = this;
 vm.project = {};
 vm.project = currentProject;
 var pid = $stateParams.pid;
 var n = vm.project.deadline;
 var d = new Date(n).toString();
 vm.update = function() {
 //Updates at FB locations with updated project
 ref.child('projects').child(pid).update({
 title: vm.project.title,
 description: vm.project.description,
 deadline: d
 });
 $mdDialog.hide();
 };
 },
 controllerAs: 'PEmodal',
 templateUrl: 'views/updateproject.html',
 parent: angular.element(document.body),
 targetEvent: e
 });

Я застрял в этой проблеме на какое-то время без решения, и был бы рад этому рассказать. Спасибо всем за ваше время.

2 ответа

Следующий код остался как есть в вопросе.

app.config(function($mdDateLocaleProvider) {
$mdDateLocaleProvider.formatDate = function(date) {
 return moment(date).format('L');
};});

Это уничтожает ошибку TypeError: date.toLocaleDateString не является функцией.

Всюду меня интересовала только эпоха. Я не понимал, что md-datepicker любит только даты. Это объясняет, почему я не мог обновить project.deadline, поскольку он читал время в эпоху. Он был в состоянии видеть это хорошо, но менял его, что приводило к ошибкам, поскольку оно не могло определить, какую дату показывать (отсюда показано 1934..).

Вместо этого я сосредоточился на работе с datepicker только с объектами даты.

Добавление нового проекта:

  • var date - это входной файл md-datepicker в формате даты. Затем я преобразую его в эпоху, чтобы сохранить его в firebase, как и другие значения.

    var date = new Date(project.deadline);
    project.deadline = date.getTime();

Обновление проекта:

  • Назначение currentProject для vm.project. Это дает мне доступ к vm.project.deadline, который включает крайний срок, который я добавил в эпоху. Преобразование крайнего срока с момента времени до объекта. Это позволяет мне изменить дату, как мне нравится. После того, как пользователь нажимает на обновление, новый объект Date сначала преобразуется в эпоху, а затем я могу добавить в firebase точно так же, как и другие данные.

    var vm = this;
    vm.project = {};
    vm.project = currentProject;
    vm.project.deadline = new Date(vm.project.deadline);
    vm.update = function() {
     var date = new Date(vm.project.deadline);
     vm.project.deadline = date.getTime();
     ...

Мне нужна эпоха, а значит, и преобразования. Если у вас нет необходимости в эпохе (или в других формах дат), я полагаю, что оставить объект даты без изменений не должен иметь никаких проблем.


У меня была та же проблема, что и вы, прежде чем добавить конфигурацию $mdDateLocaleProvider. Я продолжал получать TypeError: date.toLocaleDateString не является функцией.

Я также использовал firebase и смог проталкивать без проблем. Я даже мог видеть datepicker с сохраненным результатом, только на ref.update я получил бы ошибку. Я потратил немало времени на поиск ошибки и, наконец, обнаружил, что материал angular выполнял мою дату через функцию даты дважды из-за цикла angular digest, а во второй раз через него использовалось строковое представление js Date объект, а не сам объект даты. (следовательно, TypeError: date.toLocaleDateString не является функцией - потому что он обрабатывал дату как String, а не дату Obj.)

К сожалению, я не мог придумать исправление в своем фактическом приложении, поэтому мне пришлось зайти в источник angular -material.js и прямо перед ошибкой. Я взял дату, в которую был передан, и обеспечил ее преобразуется в дату (d = новая дата (d));

Это сработало для меня, поскольку оно всегда было либо датой, либо toString даты - в любом случае это гарантирует, что это фактический объект даты.

licensed under cc by-sa 3.0 with attribution.