Angular Material md-datepicker在单击

时间:2015-09-25 08:20:00

标签: javascript angularjs datepicker firebase angular-material

我是新来的,并且在Angular Material 0.11.0中最近可用的md-datepicker遇到了一些问题: https://material.angularjs.org/0.11.0/#/demo/material.components.datepicker

简而言之,我的应用程序允许用户添加具有名称和描述的单个项目。他们还能够更新相关的项目细节。

通过Material Designs mdDialog完成添加和更新。 用户单击添加或更新后,控制器将调用相关函数,该函数将调用我工厂中的相应函数。

工厂函数包含我已配置的$ 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');
};});

现在,我可以添加一个包含以下代码的项目,并添加'厂。我甚至可以添加我选择的日期,我可以在纪元时间将它保存到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

此时md-datepicker不知道它是哪一年并从1933年左右开始。奇怪的是,如果我没有点击图标并首先更改输入中的日期,我可以点击图标这会在正确的日期显示日历。只要我当前的mdDialog没有关闭,我就可以这样做。然后,当我点击更新时,它有时会更新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
        });

我一直坚持这个问题已经有一段时间没有解决方案,并且会对此有所了解。谢谢大家的时间。

3 个答案:

答案 0 :(得分:0)

我遇到了与添加$ mdDateLocaleProvider配置之前相同的问题。我一直得到TypeError:date.toLocaleDateString不是函数。

我也在使用firebase并且能够毫无问题地推动。我甚至可以用保存的结果查看datepicker,只有在ref.update上我才会收到错误。我花了相当多的时间来寻找这个错误,最后发现由于角度的消化周期,角度材料通过它的日期函数运行我的约会两次,第二次通过它使用字符串表示js Date对象而不是Date obj本身。 (因此TypeError:date.toLocaleDateString不是函数 - 因为它将日期视为字符串而不是日期Obj。)

不幸的是,我无法在我的实际应用程序中找到修复程序,所以我不得不进入angular-material.js源代码,并且在错误命中之前我接受了传递的日期并确保它正在转换为日期(d =新日期(d));

这对我有用,因为它总是日期或日期的toString - 无论哪种方式确保它是一个实际的日期对象。

答案 1 :(得分:0)

以下代码保留在问题中。

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

这消除了&#39; TypeError:date.toLocaleDateString不是一个函数&#39;错误。

在整个过程中,我只对这个时代感兴趣。 我没有意识到md-datepicker只喜欢日期对象。这解释了为什么我无法更新project.deadline,因为它正在读取纪元时间。它能够看到它很好,但改变它会导致错误,因为它无法确定要显示的日期(因此显示1934年......)。

相反,我专注于只使用日期对象来处理datepicker。

添加新项目:

  • var date是日期对象表单中md-datepicker的输入。 然后我将其转换为epoch,因此将其保存到firebase,就像其他值一样。

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

更新项目:

  • 将currentProject分配给vm.project。这使我可以访问vm.project.deadline,其中包括我在纪元时间中添加的截止日期。将截止日期从纪元时间转换为日期对象。这允许我根据自己的喜好更改日期。一旦用户点击更新,新的日期对象将首先转换为纪元,然后我可以像其他数据一样添加到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();
        ...
    

我需要时代因此转换。如果一个人不需要纪元(或其他日期表格),我想让日期对象保持不变应该没有问题。

答案 2 :(得分:0)

我有一个类似的错误,原因是我为输出(日期->字符串)定义了$mdDateLocale.formatDate,但我没有为输入(字符串->日期)定义$mdDateLocale.parseDate .一旦我这样做了,错误就消失了。

请注意,在 Angular 的摘要周期中,这两个函数都必须处理可能是 undefined/string/Date 的输入。因此,请务必在 .split 或 .parse 或其他任何内容之前测试输入。